From 15dc0c2000f7815a84282d0675ab84aea4365636 Mon Sep 17 00:00:00 2001 From: Gilbert Sanchez Date: Thu, 17 Sep 2026 17:13:05 -0700 Subject: [PATCH] build: rename tests/ directory to lowercase for CI portability Windows/macOS filesystems are case-insensitive; Linux is not. The PowerShellOrg reusable CI workflow (powershell-ci.yml) uploads test results from a hardcoded ./tests/out/testResults.xml path, which would silently fail to find artifacts on the ubuntu-latest runner while the directory was capitalized Tests/. Rename Tests/ -> tests/ and update the two path references: - .gitignore (tests/out/**) - psakeFile.ps1 ($PSBPreference.Test.RootDir) Prep for #488. --- .gitignore | 2 +- psakeFile.ps1 | 2 +- .../Private/Assert-UnblockedFile.Tests.ps1 | 0 .../Invoke-Koan.Control_Tests.ps1 | 0 .../ConvertFrom-WildcardPattern.Tests.ps1 | 96 ++-- .../Functions/Private/Get-KoanAst.Tests.ps1 | 0 .../Private/Get-KoanAttribute.Tests.ps1 | 0 .../Functions/Private/Get-KoanIt.Tests.ps1 | 0 .../Functions/Private/Invoke-Koan.Tests.ps1 | 0 .../Functions/Private/Measure-Koan.Tests.ps1 | 224 ++++---- .../Private/New-KoanRunspace.Tests.ps1 | 0 .../Private/New-PSKoanErrorRecord.Tests.ps1 | 0 .../Private/Update-PSKoanFile.Tests.ps1 | 208 ++++---- .../Functions/Public/Get-Blank.Tests.ps1 | 0 .../Functions/Public/Get-Karma.Tests.ps1 | 0 .../Functions/Public/Get-PSKoan.Tests.ps1 | 0 .../Public/Get-PSKoanLocation.Tests.ps1 | 0 .../Public/Get-PSKoanSetting.Tests.ps1 | 0 .../Public/Move-PSKoanLibrary.Tests.ps1 | 0 .../Public/Register-Advice.Tests.ps1 | 0 .../Functions/Public/Reset-PSKoan.Tests.ps1 | 490 +++++++++--------- .../Public/Set-PSKoanLocation.Tests.ps1 | 0 .../Public/Set-PSKoanSetting.Tests.ps1 | 0 .../Functions/Public/Show-Advice.Tests.ps1 | 0 .../Functions/Public/Show-Karma.Tests.ps1 | 0 .../Functions/Public/Update-PSKoan.Tests.ps1 | 260 +++++----- {Tests => tests}/KoanValidation.Tests.ps1 | 0 {Tests => tests}/ModuleHelp.Tests.ps1 | 0 {Tests => tests}/ModuleValidation.Tests.ps1 | 0 29 files changed, 641 insertions(+), 641 deletions(-) rename {Tests => tests}/Functions/Private/Assert-UnblockedFile.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/ControlTests/Invoke-Koan.Control_Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 (97%) rename {Tests => tests}/Functions/Private/Get-KoanAst.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/Get-KoanAttribute.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/Get-KoanIt.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/Invoke-Koan.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/Measure-Koan.Tests.ps1 (97%) rename {Tests => tests}/Functions/Private/New-KoanRunspace.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/New-PSKoanErrorRecord.Tests.ps1 (100%) rename {Tests => tests}/Functions/Private/Update-PSKoanFile.Tests.ps1 (97%) rename {Tests => tests}/Functions/Public/Get-Blank.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Get-Karma.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Get-PSKoan.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Get-PSKoanLocation.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Get-PSKoanSetting.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Move-PSKoanLibrary.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Register-Advice.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Reset-PSKoan.Tests.ps1 (97%) rename {Tests => tests}/Functions/Public/Set-PSKoanLocation.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Set-PSKoanSetting.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Show-Advice.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Show-Karma.Tests.ps1 (100%) rename {Tests => tests}/Functions/Public/Update-PSKoan.Tests.ps1 (97%) rename {Tests => tests}/KoanValidation.Tests.ps1 (100%) rename {Tests => tests}/ModuleHelp.Tests.ps1 (100%) rename {Tests => tests}/ModuleValidation.Tests.ps1 (100%) diff --git a/.gitignore b/.gitignore index 749a82be7..679f9dc55 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,5 @@ PSKoans.psproj PSKoans/*/PSKoans-help.xml Output/** -Tests/out/** +tests/out/** testResults.xml diff --git a/psakeFile.ps1 b/psakeFile.ps1 index 4d5fee156..c33fa5aed 100644 --- a/psakeFile.ps1 +++ b/psakeFile.ps1 @@ -7,7 +7,7 @@ Properties { # Test configuration -- the module must be imported from the staged output before # Pester runs since the test suite expects `PSKoans` to already be loaded/resolvable - $PSBPreference.Test.RootDir = Join-Path $PSScriptRoot 'Tests' + $PSBPreference.Test.RootDir = Join-Path $PSScriptRoot 'tests' $PSBPreference.Test.ImportModule = $true $PSBPreference.Test.OutputFile = 'out/testResults.xml' $PSBPreference.Test.OutputFormat = 'JUnitXml' diff --git a/Tests/Functions/Private/Assert-UnblockedFile.Tests.ps1 b/tests/Functions/Private/Assert-UnblockedFile.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/Assert-UnblockedFile.Tests.ps1 rename to tests/Functions/Private/Assert-UnblockedFile.Tests.ps1 diff --git a/Tests/Functions/Private/ControlTests/Invoke-Koan.Control_Tests.ps1 b/tests/Functions/Private/ControlTests/Invoke-Koan.Control_Tests.ps1 similarity index 100% rename from Tests/Functions/Private/ControlTests/Invoke-Koan.Control_Tests.ps1 rename to tests/Functions/Private/ControlTests/Invoke-Koan.Control_Tests.ps1 diff --git a/Tests/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 b/tests/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 similarity index 97% rename from Tests/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 rename to tests/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 index 94fd3f29c..8c9da83e8 100644 --- a/Tests/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 +++ b/tests/Functions/Private/ConvertFrom-WildcardPattern.Tests.ps1 @@ -1,48 +1,48 @@ -#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } - -BeforeDiscovery { - if ($null -eq $env:BHProjectName) { - # Run the build in a child process -- build.ps1 calls `exit` on completion, which - # would otherwise terminate the host process running this test file. - & pwsh -NoProfile -File '.\build.ps1' -Task Build - if ($LASTEXITCODE -ne 0) { - throw 'Failed to build PSKoans before running tests.' - } - Set-BuildEnvironment -Force - } - $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest - $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' - $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName - $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion - $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" - $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath - - # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore - Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop -} - -Describe 'ConvertFrom-WildcardPattern' { - - It 'adds start and end of string anchors to an explicit value' { - InModuleScope 'PSKoans' { ConvertFrom-WildcardPattern 'AboutArrays' } | Should -Be '^AboutArrays$' - } - - It 'joins multiple expressions with |' { - InModuleScope 'PSKoans' { ConvertFrom-WildcardPattern 'AboutArrays', 'AboutComparison' } | - Should -Be '^AboutArrays$|^AboutComparison$' - } - - It 'replaces wildcard characters with regex equivalent' -TestCases @( - @{ Pattern = 'About*son'; Expected = '^About.*son$' } - @{ Pattern = 'AboutArrays*'; Expected = '^AboutArrays' } - @{ Pattern = '*Arrays'; Expected = 'Arrays$' } - @{ Pattern = '*Array*'; Expected = 'Array' } - ) { - InModuleScope 'PSKoans' -Parameters @{ Pattern = $Pattern } { - param($Pattern) - - ConvertFrom-WildcardPattern $Pattern - } | Should -Be $Expected - } -} +#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } + +BeforeDiscovery { + if ($null -eq $env:BHProjectName) { + # Run the build in a child process -- build.ps1 calls `exit` on completion, which + # would otherwise terminate the host process running this test file. + & pwsh -NoProfile -File '.\build.ps1' -Task Build + if ($LASTEXITCODE -ne 0) { + throw 'Failed to build PSKoans before running tests.' + } + Set-BuildEnvironment -Force + } + $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest + $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' + $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName + $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion + $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" + $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath + + # Remove all versions of the module from the session. Pester can't handle multiple versions. + Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore + Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop +} + +Describe 'ConvertFrom-WildcardPattern' { + + It 'adds start and end of string anchors to an explicit value' { + InModuleScope 'PSKoans' { ConvertFrom-WildcardPattern 'AboutArrays' } | Should -Be '^AboutArrays$' + } + + It 'joins multiple expressions with |' { + InModuleScope 'PSKoans' { ConvertFrom-WildcardPattern 'AboutArrays', 'AboutComparison' } | + Should -Be '^AboutArrays$|^AboutComparison$' + } + + It 'replaces wildcard characters with regex equivalent' -TestCases @( + @{ Pattern = 'About*son'; Expected = '^About.*son$' } + @{ Pattern = 'AboutArrays*'; Expected = '^AboutArrays' } + @{ Pattern = '*Arrays'; Expected = 'Arrays$' } + @{ Pattern = '*Array*'; Expected = 'Array' } + ) { + InModuleScope 'PSKoans' -Parameters @{ Pattern = $Pattern } { + param($Pattern) + + ConvertFrom-WildcardPattern $Pattern + } | Should -Be $Expected + } +} diff --git a/Tests/Functions/Private/Get-KoanAst.Tests.ps1 b/tests/Functions/Private/Get-KoanAst.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/Get-KoanAst.Tests.ps1 rename to tests/Functions/Private/Get-KoanAst.Tests.ps1 diff --git a/Tests/Functions/Private/Get-KoanAttribute.Tests.ps1 b/tests/Functions/Private/Get-KoanAttribute.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/Get-KoanAttribute.Tests.ps1 rename to tests/Functions/Private/Get-KoanAttribute.Tests.ps1 diff --git a/Tests/Functions/Private/Get-KoanIt.Tests.ps1 b/tests/Functions/Private/Get-KoanIt.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/Get-KoanIt.Tests.ps1 rename to tests/Functions/Private/Get-KoanIt.Tests.ps1 diff --git a/Tests/Functions/Private/Invoke-Koan.Tests.ps1 b/tests/Functions/Private/Invoke-Koan.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/Invoke-Koan.Tests.ps1 rename to tests/Functions/Private/Invoke-Koan.Tests.ps1 diff --git a/Tests/Functions/Private/Measure-Koan.Tests.ps1 b/tests/Functions/Private/Measure-Koan.Tests.ps1 similarity index 97% rename from Tests/Functions/Private/Measure-Koan.Tests.ps1 rename to tests/Functions/Private/Measure-Koan.Tests.ps1 index 393e8b18e..a6cabb209 100644 --- a/Tests/Functions/Private/Measure-Koan.Tests.ps1 +++ b/tests/Functions/Private/Measure-Koan.Tests.ps1 @@ -1,112 +1,112 @@ -#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } - -BeforeDiscovery { - if ($null -eq $env:BHProjectName) { - # Run the build in a child process -- build.ps1 calls `exit` on completion, which - # would otherwise terminate the host process running this test file. - & pwsh -NoProfile -File '.\build.ps1' -Task Build - if ($LASTEXITCODE -ne 0) { - throw 'Failed to build PSKoans before running tests.' - } - Set-BuildEnvironment -Force - } - $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest - $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' - $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName - $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion - $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" - $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath - - # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore - Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop -} - -Describe 'Measure-Koan' -Skip { - - BeforeAll { - Set-Content -Path 'TestDrive:\TestCases.Koans.ps1' -Value @' - Describe 'Test cases param' { - It 'first ' -TestCases @( - @{ TestCase = 1 } - @{ TestCase = 2 } - @{ TestCase = 3 } - ) { - param($TestCase) - - $TestCase | Should -BeOfType int - } - } -'@ - - Set-Content -Path 'TestDrive:\JustIt.Koans.ps1' -Value @' - Describe 'Just it' { - It 'first' { - $true | Should -BeTrue - } - - It 'second' { - $true | Should -BeTrue - } - } -'@ - - Set-Content -Path TestDrive:\Mixed.Koans.ps1 -Value @' - Describe 'Mixed' { - It 'first' { - $true | Should -BeTrue - } - - It 'second ' -TestCases @( - @{ TestCase = 1 } - @{ TestCase = 2 } - ) { - param($TestCase) - - $TestCase | Should -BeOfType int - } - } -'@ - - Set-Content -Path TestDrive:\MutlipleTestCases.Koans.ps1 -Value @' - Describe 'Test cases param' { - It 'first ' -TestCases @( - @{ TestCase = 1 } - @{ TestCase = 2 } - @{ TestCase = 3 } - ) { - param($TestCase) - - $TestCase | Should -BeOfType int - } - - It 'second ' -TestCases @( - @{ TestCase = 1 } - @{ TestCase = 2 } - @{ TestCase = 3 } - ) { - param($TestCase) - - $TestCase | Should -BeOfType int - } - } -'@ - } - - It 'correctly counts the number of tests in , including -TestCases' -TestCases @( - @{ Path = 'TestDrive:\TestCases.Koans.ps1'; ExpectedValue = 3 } - @{ Path = 'TestDrive:\JustIt.Koans.ps1'; ExpectedValue = 2 } - @{ Path = 'TestDrive:\Mixed.Koans.ps1'; ExpectedValue = 3 } - @{ Path = 'TestDrive:\MutlipleTestCases.Koans.ps1'; ExpectedValue = 6 } - ) { - $koanInfo = [PSCustomObject]@{ - Path = $Path - PSTypeName = 'PSKoans.KoanInfo' - } - - InModuleScope 'PSKoans' -Parameters @{ Koan = $koanInfo } { - param($Koan) - Measure-Koan $Koan - } | Should -Be $ExpectedValue - } -} +#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } + +BeforeDiscovery { + if ($null -eq $env:BHProjectName) { + # Run the build in a child process -- build.ps1 calls `exit` on completion, which + # would otherwise terminate the host process running this test file. + & pwsh -NoProfile -File '.\build.ps1' -Task Build + if ($LASTEXITCODE -ne 0) { + throw 'Failed to build PSKoans before running tests.' + } + Set-BuildEnvironment -Force + } + $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest + $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' + $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName + $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion + $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" + $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath + + # Remove all versions of the module from the session. Pester can't handle multiple versions. + Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore + Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop +} + +Describe 'Measure-Koan' -Skip { + + BeforeAll { + Set-Content -Path 'TestDrive:\TestCases.Koans.ps1' -Value @' + Describe 'Test cases param' { + It 'first ' -TestCases @( + @{ TestCase = 1 } + @{ TestCase = 2 } + @{ TestCase = 3 } + ) { + param($TestCase) + + $TestCase | Should -BeOfType int + } + } +'@ + + Set-Content -Path 'TestDrive:\JustIt.Koans.ps1' -Value @' + Describe 'Just it' { + It 'first' { + $true | Should -BeTrue + } + + It 'second' { + $true | Should -BeTrue + } + } +'@ + + Set-Content -Path TestDrive:\Mixed.Koans.ps1 -Value @' + Describe 'Mixed' { + It 'first' { + $true | Should -BeTrue + } + + It 'second ' -TestCases @( + @{ TestCase = 1 } + @{ TestCase = 2 } + ) { + param($TestCase) + + $TestCase | Should -BeOfType int + } + } +'@ + + Set-Content -Path TestDrive:\MutlipleTestCases.Koans.ps1 -Value @' + Describe 'Test cases param' { + It 'first ' -TestCases @( + @{ TestCase = 1 } + @{ TestCase = 2 } + @{ TestCase = 3 } + ) { + param($TestCase) + + $TestCase | Should -BeOfType int + } + + It 'second ' -TestCases @( + @{ TestCase = 1 } + @{ TestCase = 2 } + @{ TestCase = 3 } + ) { + param($TestCase) + + $TestCase | Should -BeOfType int + } + } +'@ + } + + It 'correctly counts the number of tests in , including -TestCases' -TestCases @( + @{ Path = 'TestDrive:\TestCases.Koans.ps1'; ExpectedValue = 3 } + @{ Path = 'TestDrive:\JustIt.Koans.ps1'; ExpectedValue = 2 } + @{ Path = 'TestDrive:\Mixed.Koans.ps1'; ExpectedValue = 3 } + @{ Path = 'TestDrive:\MutlipleTestCases.Koans.ps1'; ExpectedValue = 6 } + ) { + $koanInfo = [PSCustomObject]@{ + Path = $Path + PSTypeName = 'PSKoans.KoanInfo' + } + + InModuleScope 'PSKoans' -Parameters @{ Koan = $koanInfo } { + param($Koan) + Measure-Koan $Koan + } | Should -Be $ExpectedValue + } +} diff --git a/Tests/Functions/Private/New-KoanRunspace.Tests.ps1 b/tests/Functions/Private/New-KoanRunspace.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/New-KoanRunspace.Tests.ps1 rename to tests/Functions/Private/New-KoanRunspace.Tests.ps1 diff --git a/Tests/Functions/Private/New-PSKoanErrorRecord.Tests.ps1 b/tests/Functions/Private/New-PSKoanErrorRecord.Tests.ps1 similarity index 100% rename from Tests/Functions/Private/New-PSKoanErrorRecord.Tests.ps1 rename to tests/Functions/Private/New-PSKoanErrorRecord.Tests.ps1 diff --git a/Tests/Functions/Private/Update-PSKoanFile.Tests.ps1 b/tests/Functions/Private/Update-PSKoanFile.Tests.ps1 similarity index 97% rename from Tests/Functions/Private/Update-PSKoanFile.Tests.ps1 rename to tests/Functions/Private/Update-PSKoanFile.Tests.ps1 index 09c5659b8..6688efc08 100644 --- a/Tests/Functions/Private/Update-PSKoanFile.Tests.ps1 +++ b/tests/Functions/Private/Update-PSKoanFile.Tests.ps1 @@ -1,104 +1,104 @@ -#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } - -BeforeDiscovery { - if ($null -eq $env:BHProjectName) { - # Run the build in a child process -- build.ps1 calls `exit` on completion, which - # would otherwise terminate the host process running this test file. - & pwsh -NoProfile -File '.\build.ps1' -Task Build - if ($LASTEXITCODE -ne 0) { - throw 'Failed to build PSKoans before running tests.' - } - Set-BuildEnvironment -Force - } - $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest - $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' - $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName - $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion - $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" - $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath - - # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore - Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop -} - -Describe 'Update-PSKoanFile' { - - BeforeAll { - $koanLocation = Join-Path -Path $TestDrive -ChildPath 'Koans' - $koanRelativePath = 'Group/AboutSomething.ps1' - $moduleKoanPath = Join-Path -Path $TestDrive -ChildPath 'Module/Group/AboutSomething.ps1' - - Mock 'Get-PSKoanLocation' -ModuleName 'PSKoans' { $koanLocation } - Mock 'Get-PSKoan' -ModuleName 'PSKoans' { - [PSCustomObject]@{ - Topic = 'AboutSomething' - Path = $moduleKoanPath - RelativePath = $koanRelativePath - } - } - - New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'Koans/Group') -ItemType Directory - New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'Module/Group') -ItemType Directory - - Set-Content -Path $moduleKoanPath -Value @' - Describe 'AboutSomething' { - It 'koan 1' { - __ | Should -Be 1 - } - - It 'koan 2' { - __ | Should -Be 2 - } - - Context 'first' { - It 'koan 3' { - __ | Should -Be 3 - } - } - - Context 'second' { - It 'koan 4' { - __ | Should -Be 4 - } - } - } -'@ - - $userFilePath = Join-Path -Path $koanLocation -ChildPath $koanRelativePath - } - - BeforeEach { - Set-Content -Path $userFilePath -Value @' - Describe 'AboutSomething' { - It 'koan 1' { - 1 | Should -Be 1 - } - - It 'koan 2' { - __ | Should -Be 2 - } - - Context 'second' { - It 'koan 4' { - 4 | Should -Be 4 - } - } - } -'@ - } - - It 'should replay completed koans' { - InModuleScope 'PSKoans' { Update-PSKoanFile -Topic AboutSomething -Confirm:$false } - - $userFilePath | Should -FileContentMatch '1 | Should -Be 1' - $userFilePath | Should -FileContentMatch '__ | Should -Be 2' - $userFilePath | Should -FileContentMatch '4 | Should -Be 4' - } - - It 'should should allow new koans to be inserted' { - InModuleScope 'PSKoans' { Update-PSKoanFile -Topic AboutSomething -Confirm:$false } - - $userFilePath | Should -FileContentMatch 'koan 3' - } -} +#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } + +BeforeDiscovery { + if ($null -eq $env:BHProjectName) { + # Run the build in a child process -- build.ps1 calls `exit` on completion, which + # would otherwise terminate the host process running this test file. + & pwsh -NoProfile -File '.\build.ps1' -Task Build + if ($LASTEXITCODE -ne 0) { + throw 'Failed to build PSKoans before running tests.' + } + Set-BuildEnvironment -Force + } + $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest + $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' + $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName + $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion + $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" + $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath + + # Remove all versions of the module from the session. Pester can't handle multiple versions. + Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore + Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop +} + +Describe 'Update-PSKoanFile' { + + BeforeAll { + $koanLocation = Join-Path -Path $TestDrive -ChildPath 'Koans' + $koanRelativePath = 'Group/AboutSomething.ps1' + $moduleKoanPath = Join-Path -Path $TestDrive -ChildPath 'Module/Group/AboutSomething.ps1' + + Mock 'Get-PSKoanLocation' -ModuleName 'PSKoans' { $koanLocation } + Mock 'Get-PSKoan' -ModuleName 'PSKoans' { + [PSCustomObject]@{ + Topic = 'AboutSomething' + Path = $moduleKoanPath + RelativePath = $koanRelativePath + } + } + + New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'Koans/Group') -ItemType Directory + New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'Module/Group') -ItemType Directory + + Set-Content -Path $moduleKoanPath -Value @' + Describe 'AboutSomething' { + It 'koan 1' { + __ | Should -Be 1 + } + + It 'koan 2' { + __ | Should -Be 2 + } + + Context 'first' { + It 'koan 3' { + __ | Should -Be 3 + } + } + + Context 'second' { + It 'koan 4' { + __ | Should -Be 4 + } + } + } +'@ + + $userFilePath = Join-Path -Path $koanLocation -ChildPath $koanRelativePath + } + + BeforeEach { + Set-Content -Path $userFilePath -Value @' + Describe 'AboutSomething' { + It 'koan 1' { + 1 | Should -Be 1 + } + + It 'koan 2' { + __ | Should -Be 2 + } + + Context 'second' { + It 'koan 4' { + 4 | Should -Be 4 + } + } + } +'@ + } + + It 'should replay completed koans' { + InModuleScope 'PSKoans' { Update-PSKoanFile -Topic AboutSomething -Confirm:$false } + + $userFilePath | Should -FileContentMatch '1 | Should -Be 1' + $userFilePath | Should -FileContentMatch '__ | Should -Be 2' + $userFilePath | Should -FileContentMatch '4 | Should -Be 4' + } + + It 'should should allow new koans to be inserted' { + InModuleScope 'PSKoans' { Update-PSKoanFile -Topic AboutSomething -Confirm:$false } + + $userFilePath | Should -FileContentMatch 'koan 3' + } +} diff --git a/Tests/Functions/Public/Get-Blank.Tests.ps1 b/tests/Functions/Public/Get-Blank.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Get-Blank.Tests.ps1 rename to tests/Functions/Public/Get-Blank.Tests.ps1 diff --git a/Tests/Functions/Public/Get-Karma.Tests.ps1 b/tests/Functions/Public/Get-Karma.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Get-Karma.Tests.ps1 rename to tests/Functions/Public/Get-Karma.Tests.ps1 diff --git a/Tests/Functions/Public/Get-PSKoan.Tests.ps1 b/tests/Functions/Public/Get-PSKoan.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Get-PSKoan.Tests.ps1 rename to tests/Functions/Public/Get-PSKoan.Tests.ps1 diff --git a/Tests/Functions/Public/Get-PSKoanLocation.Tests.ps1 b/tests/Functions/Public/Get-PSKoanLocation.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Get-PSKoanLocation.Tests.ps1 rename to tests/Functions/Public/Get-PSKoanLocation.Tests.ps1 diff --git a/Tests/Functions/Public/Get-PSKoanSetting.Tests.ps1 b/tests/Functions/Public/Get-PSKoanSetting.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Get-PSKoanSetting.Tests.ps1 rename to tests/Functions/Public/Get-PSKoanSetting.Tests.ps1 diff --git a/Tests/Functions/Public/Move-PSKoanLibrary.Tests.ps1 b/tests/Functions/Public/Move-PSKoanLibrary.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Move-PSKoanLibrary.Tests.ps1 rename to tests/Functions/Public/Move-PSKoanLibrary.Tests.ps1 diff --git a/Tests/Functions/Public/Register-Advice.Tests.ps1 b/tests/Functions/Public/Register-Advice.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Register-Advice.Tests.ps1 rename to tests/Functions/Public/Register-Advice.Tests.ps1 diff --git a/Tests/Functions/Public/Reset-PSKoan.Tests.ps1 b/tests/Functions/Public/Reset-PSKoan.Tests.ps1 similarity index 97% rename from Tests/Functions/Public/Reset-PSKoan.Tests.ps1 rename to tests/Functions/Public/Reset-PSKoan.Tests.ps1 index 7dc9e7d99..3b80cecd6 100644 --- a/Tests/Functions/Public/Reset-PSKoan.Tests.ps1 +++ b/tests/Functions/Public/Reset-PSKoan.Tests.ps1 @@ -1,245 +1,245 @@ -#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } - -BeforeDiscovery { - if ($null -eq $env:BHProjectName) { - # Run the build in a child process -- build.ps1 calls `exit` on completion, which - # would otherwise terminate the host process running this test file. - & pwsh -NoProfile -File '.\build.ps1' -Task Build - if ($LASTEXITCODE -ne 0) { - throw 'Failed to build PSKoans before running tests.' - } - Set-BuildEnvironment -Force - } - $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest - $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' - $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName - $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion - $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" - $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath - - # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore - Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop -} - -Describe Reset-PSKoan { - - BeforeAll { - $defaultParams = @{ - Confirm = $false - } - - $koanLocation = Join-Path -Path $TestDrive -ChildPath 'PSKoans' - $moduleKoanPath = Join-Path -Path $TestDrive -ChildPath 'Module\Group\AboutSomething.Koans.ps1' - - Mock 'Get-PSKoanLocation' -ModuleName 'PSKoans' { $koanLocation } - - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' -MockWith { - [PSCustomObject]@{ - Topic = 'AboutSomething' - Path = $moduleKoanPath - RelativePath = 'Group\AboutSomething.Koans.ps1' - } - } - - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -ModuleName 'PSKoans' -MockWith { - [PSCustomObject]@{ - Topic = 'AboutSomething' - Path = $userFilePath - RelativePath = 'Group\AboutSomething.Koans.ps1' - } - } - - New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'Module\Group') -ItemType Directory - New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'PSKoans\Group') -ItemType Directory - - $userFilePath = Join-Path -Path $koanLocation -ChildPath 'Group\AboutSomething.Koans.ps1' - - Set-Content -Path $moduleKoanPath, $userFilePath -Value @' - using module PSKoans - [Koan(Position = 1)] - param ( ) - - Describe 'AboutSomething' { - It 'existing content' { - __ | Should -Be 1 - } - - It 'reset content' { - __ | Should -Be 2 - } - - Context 'first' { - It 'nested reset content' { - __ | Should -Be 3 - } - } - - Context 'second' { - It 'nested reset content' { - __ | Should -Be 4 - } - } - } -'@ - } - - Context 'User file exists, It block exists' { - - BeforeAll { - Mock 'Set-Content' -ModuleName 'PSKoans' - Mock 'Copy-Item' -ModuleName 'PSKoans' - } - - It 'updates an existing user file when -Name is supplied' { - Reset-PSKoan -Name 'existing content' @defaultParams - - Should -Invoke 'Set-Content' -Times 1 -ModuleName 'PSKoans' - Should -Invoke 'Copy-Item' -Times 0 -ModuleName 'PSKoans' - } - - It 'updates an existing user file when -Context is supplied' { - Reset-PSKoan -Context 'first' @defaultParams - - Should -Invoke 'Set-Content' -Times 1 -Exactly -ModuleName 'PSKoans' - Should -Invoke 'Copy-Item' -Times 0 -ModuleName 'PSKoans' - } - - It 'updates an existing user file when -Name and -Context are supplied' { - Reset-PSKoan -Name 'nested reset content' -Context 'first' @defaultParams - - Should -Invoke 'Set-Content' -Times 1 -Exactly -ModuleName 'PSKoans' - Should -Invoke 'Copy-Item' -Times 0 -ModuleName 'PSKoans' - } - - It 'copies a koan file from the module when -Name and -Context are not supplied' { - Reset-PSKoan @defaultParams - - Should -Invoke 'Set-Content' -Times 0 -ModuleName 'PSKoans' - Should -Invoke 'Copy-Item' -Times 1 -Exactly -ModuleName 'PSKoans' - } - } - - Context 'User file exists, It block does not exist' { - - It 'writes a non-terminating error when the user file does not include the specified Koan' { - $realGetKoanIt = InModuleScope 'PSKoans' { Get-Item -Path 'Function:\Get-KoanIt' } - Mock 'Get-KoanIt' -ModuleName 'PSKoans' -MockWith { & $realGetKoanIt @args } - Mock 'Get-KoanIt' -ParameterFilter { $Path -match 'PSKoans' } -ModuleName 'PSKoans' - - { Reset-PSKoan -Topic AboutSomething -Name 'existing content' -ErrorAction Stop @defaultParams } | - Should -Throw -ErrorId 'PSKoans.UserItNotFound,Reset-PSKoan' - } - } - - Context 'User file does not exist' { - - BeforeAll { - New-Item "$TestDrive/DoesNotExist.Koans.ps1" -ItemType File > $null - - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -Verifiable -ModuleName 'PSKoans' - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -Verifiable -ModuleName 'PSKoans' -MockWith { - [PSCustomObject]@{ - Topic = $Topic - Module = '_powershell' - Position = 101 - Path = "$TestDrive/DoesNotExist.Koans.ps1" - RelativePath = 'DoesNotExist.Koans.ps1' - PSTypeName = 'PSKoans.KoanInfo' - } - } - - Mock 'Update-PSKoan' -ModuleName 'PSKoans' - } - - It 'calls Update-PSKoan when the topic does not exist in the user location' { - Reset-PSKoan -Topic DoesNotExist -ErrorAction Stop @defaultParams - - Should -InvokeVerifiable - Should -Invoke Update-PSKoan -Times 1 -Exactly -ModuleName 'PSKoans' - } - } - - Context 'Module file does not exist' { - - BeforeAll { - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -ModuleName 'PSKoans' - } - - It 'throws a terminating error when no topics are found in the module' { - { Reset-PSKoan -Topic DoesNotExist @defaultParams } | - Should -Throw -ErrorId 'PSKoans.ModuleTopicNotFound,Reset-PSKoan' - - Should -Invoke 'Get-PSKoan' -Times 1 -Exactly -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' - } - } - - Context 'Practical tests' { - - BeforeEach { - Set-Content -Path $userFilePath -Value @' - using module PSKoans - [Koan(Position = 1)] - param ( ) - - Describe 'AboutSomething' { - It 'existing content' { - 1 | Should -Be 1 - } - - It 'reset content' { - 1 | Should -Be 2 - } - - Context 'first' { - It 'nested reset content' { - 3 | Should -Be 3 - } - } - - Context 'second' { - It 'nested reset content' { - 4 | Should -Be 4 - } - } - } -'@ - } - - It 'should reset all koans in a file when Name is not specified' { - $userFilePath | Should -FileContentMatch '__ | Should -Be 1' - $userFilePath | Should -FileContentMatch '__ | Should -Be 2' - $userFilePath | Should -FileContentMatch '__ | Should -Be 3' - $userFilePath | Should -FileContentMatch '__ | Should -Be 4' - } - - It 'should reset the state of a single koan without affecting others when Name is specified' { - Reset-PSKoan -Topic AboutSomething -Name 'reset content' @defaultParams - - $userFilePath | Should -FileContentMatch '1 | Should -Be 1' - $userFilePath | Should -FileContentMatch '__ | Should -Be 2' - } - - It 'supports context based searching' { - Reset-PSKoan -Topic AboutSomething -Name "nested reset content" -Context 'first' @defaultParams - - $userFilePath | Should -FileContentMatch '__ | Should -Be 3' - $userFilePath | Should -FileContentMatch '4 | Should -Be 4' - } - - It 'allows koans of a given name to be reset across all contexts' { - Reset-PSKoan -Topic AboutSomething -Name "nested reset content" @defaultParams - - $userFilePath | Should -FileContentMatch '__ | Should -Be 3' - $userFilePath | Should -FileContentMatch '__ | Should -Be 4' - } - - It 'supports wildcard patterns when matching name' { - Reset-PSKoan -Topic AboutSomething -Name "*content" @defaultParams - - $userFilePath | Should -FileContentMatch '__ | Should -Be 1' - $userFilePath | Should -FileContentMatch '__ | Should -Be 2' - } - } -} +#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } + +BeforeDiscovery { + if ($null -eq $env:BHProjectName) { + # Run the build in a child process -- build.ps1 calls `exit` on completion, which + # would otherwise terminate the host process running this test file. + & pwsh -NoProfile -File '.\build.ps1' -Task Build + if ($LASTEXITCODE -ne 0) { + throw 'Failed to build PSKoans before running tests.' + } + Set-BuildEnvironment -Force + } + $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest + $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' + $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName + $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion + $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" + $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath + + # Remove all versions of the module from the session. Pester can't handle multiple versions. + Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore + Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop +} + +Describe Reset-PSKoan { + + BeforeAll { + $defaultParams = @{ + Confirm = $false + } + + $koanLocation = Join-Path -Path $TestDrive -ChildPath 'PSKoans' + $moduleKoanPath = Join-Path -Path $TestDrive -ChildPath 'Module\Group\AboutSomething.Koans.ps1' + + Mock 'Get-PSKoanLocation' -ModuleName 'PSKoans' { $koanLocation } + + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' -MockWith { + [PSCustomObject]@{ + Topic = 'AboutSomething' + Path = $moduleKoanPath + RelativePath = 'Group\AboutSomething.Koans.ps1' + } + } + + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -ModuleName 'PSKoans' -MockWith { + [PSCustomObject]@{ + Topic = 'AboutSomething' + Path = $userFilePath + RelativePath = 'Group\AboutSomething.Koans.ps1' + } + } + + New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'Module\Group') -ItemType Directory + New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'PSKoans\Group') -ItemType Directory + + $userFilePath = Join-Path -Path $koanLocation -ChildPath 'Group\AboutSomething.Koans.ps1' + + Set-Content -Path $moduleKoanPath, $userFilePath -Value @' + using module PSKoans + [Koan(Position = 1)] + param ( ) + + Describe 'AboutSomething' { + It 'existing content' { + __ | Should -Be 1 + } + + It 'reset content' { + __ | Should -Be 2 + } + + Context 'first' { + It 'nested reset content' { + __ | Should -Be 3 + } + } + + Context 'second' { + It 'nested reset content' { + __ | Should -Be 4 + } + } + } +'@ + } + + Context 'User file exists, It block exists' { + + BeforeAll { + Mock 'Set-Content' -ModuleName 'PSKoans' + Mock 'Copy-Item' -ModuleName 'PSKoans' + } + + It 'updates an existing user file when -Name is supplied' { + Reset-PSKoan -Name 'existing content' @defaultParams + + Should -Invoke 'Set-Content' -Times 1 -ModuleName 'PSKoans' + Should -Invoke 'Copy-Item' -Times 0 -ModuleName 'PSKoans' + } + + It 'updates an existing user file when -Context is supplied' { + Reset-PSKoan -Context 'first' @defaultParams + + Should -Invoke 'Set-Content' -Times 1 -Exactly -ModuleName 'PSKoans' + Should -Invoke 'Copy-Item' -Times 0 -ModuleName 'PSKoans' + } + + It 'updates an existing user file when -Name and -Context are supplied' { + Reset-PSKoan -Name 'nested reset content' -Context 'first' @defaultParams + + Should -Invoke 'Set-Content' -Times 1 -Exactly -ModuleName 'PSKoans' + Should -Invoke 'Copy-Item' -Times 0 -ModuleName 'PSKoans' + } + + It 'copies a koan file from the module when -Name and -Context are not supplied' { + Reset-PSKoan @defaultParams + + Should -Invoke 'Set-Content' -Times 0 -ModuleName 'PSKoans' + Should -Invoke 'Copy-Item' -Times 1 -Exactly -ModuleName 'PSKoans' + } + } + + Context 'User file exists, It block does not exist' { + + It 'writes a non-terminating error when the user file does not include the specified Koan' { + $realGetKoanIt = InModuleScope 'PSKoans' { Get-Item -Path 'Function:\Get-KoanIt' } + Mock 'Get-KoanIt' -ModuleName 'PSKoans' -MockWith { & $realGetKoanIt @args } + Mock 'Get-KoanIt' -ParameterFilter { $Path -match 'PSKoans' } -ModuleName 'PSKoans' + + { Reset-PSKoan -Topic AboutSomething -Name 'existing content' -ErrorAction Stop @defaultParams } | + Should -Throw -ErrorId 'PSKoans.UserItNotFound,Reset-PSKoan' + } + } + + Context 'User file does not exist' { + + BeforeAll { + New-Item "$TestDrive/DoesNotExist.Koans.ps1" -ItemType File > $null + + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -Verifiable -ModuleName 'PSKoans' + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -Verifiable -ModuleName 'PSKoans' -MockWith { + [PSCustomObject]@{ + Topic = $Topic + Module = '_powershell' + Position = 101 + Path = "$TestDrive/DoesNotExist.Koans.ps1" + RelativePath = 'DoesNotExist.Koans.ps1' + PSTypeName = 'PSKoans.KoanInfo' + } + } + + Mock 'Update-PSKoan' -ModuleName 'PSKoans' + } + + It 'calls Update-PSKoan when the topic does not exist in the user location' { + Reset-PSKoan -Topic DoesNotExist -ErrorAction Stop @defaultParams + + Should -InvokeVerifiable + Should -Invoke Update-PSKoan -Times 1 -Exactly -ModuleName 'PSKoans' + } + } + + Context 'Module file does not exist' { + + BeforeAll { + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -ModuleName 'PSKoans' + } + + It 'throws a terminating error when no topics are found in the module' { + { Reset-PSKoan -Topic DoesNotExist @defaultParams } | + Should -Throw -ErrorId 'PSKoans.ModuleTopicNotFound,Reset-PSKoan' + + Should -Invoke 'Get-PSKoan' -Times 1 -Exactly -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' + } + } + + Context 'Practical tests' { + + BeforeEach { + Set-Content -Path $userFilePath -Value @' + using module PSKoans + [Koan(Position = 1)] + param ( ) + + Describe 'AboutSomething' { + It 'existing content' { + 1 | Should -Be 1 + } + + It 'reset content' { + 1 | Should -Be 2 + } + + Context 'first' { + It 'nested reset content' { + 3 | Should -Be 3 + } + } + + Context 'second' { + It 'nested reset content' { + 4 | Should -Be 4 + } + } + } +'@ + } + + It 'should reset all koans in a file when Name is not specified' { + $userFilePath | Should -FileContentMatch '__ | Should -Be 1' + $userFilePath | Should -FileContentMatch '__ | Should -Be 2' + $userFilePath | Should -FileContentMatch '__ | Should -Be 3' + $userFilePath | Should -FileContentMatch '__ | Should -Be 4' + } + + It 'should reset the state of a single koan without affecting others when Name is specified' { + Reset-PSKoan -Topic AboutSomething -Name 'reset content' @defaultParams + + $userFilePath | Should -FileContentMatch '1 | Should -Be 1' + $userFilePath | Should -FileContentMatch '__ | Should -Be 2' + } + + It 'supports context based searching' { + Reset-PSKoan -Topic AboutSomething -Name "nested reset content" -Context 'first' @defaultParams + + $userFilePath | Should -FileContentMatch '__ | Should -Be 3' + $userFilePath | Should -FileContentMatch '4 | Should -Be 4' + } + + It 'allows koans of a given name to be reset across all contexts' { + Reset-PSKoan -Topic AboutSomething -Name "nested reset content" @defaultParams + + $userFilePath | Should -FileContentMatch '__ | Should -Be 3' + $userFilePath | Should -FileContentMatch '__ | Should -Be 4' + } + + It 'supports wildcard patterns when matching name' { + Reset-PSKoan -Topic AboutSomething -Name "*content" @defaultParams + + $userFilePath | Should -FileContentMatch '__ | Should -Be 1' + $userFilePath | Should -FileContentMatch '__ | Should -Be 2' + } + } +} diff --git a/Tests/Functions/Public/Set-PSKoanLocation.Tests.ps1 b/tests/Functions/Public/Set-PSKoanLocation.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Set-PSKoanLocation.Tests.ps1 rename to tests/Functions/Public/Set-PSKoanLocation.Tests.ps1 diff --git a/Tests/Functions/Public/Set-PSKoanSetting.Tests.ps1 b/tests/Functions/Public/Set-PSKoanSetting.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Set-PSKoanSetting.Tests.ps1 rename to tests/Functions/Public/Set-PSKoanSetting.Tests.ps1 diff --git a/Tests/Functions/Public/Show-Advice.Tests.ps1 b/tests/Functions/Public/Show-Advice.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Show-Advice.Tests.ps1 rename to tests/Functions/Public/Show-Advice.Tests.ps1 diff --git a/Tests/Functions/Public/Show-Karma.Tests.ps1 b/tests/Functions/Public/Show-Karma.Tests.ps1 similarity index 100% rename from Tests/Functions/Public/Show-Karma.Tests.ps1 rename to tests/Functions/Public/Show-Karma.Tests.ps1 diff --git a/Tests/Functions/Public/Update-PSKoan.Tests.ps1 b/tests/Functions/Public/Update-PSKoan.Tests.ps1 similarity index 97% rename from Tests/Functions/Public/Update-PSKoan.Tests.ps1 rename to tests/Functions/Public/Update-PSKoan.Tests.ps1 index 921dd396d..0d6819b74 100644 --- a/Tests/Functions/Public/Update-PSKoan.Tests.ps1 +++ b/tests/Functions/Public/Update-PSKoan.Tests.ps1 @@ -1,130 +1,130 @@ -#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } - -BeforeDiscovery { - if ($null -eq $env:BHProjectName) { - # Run the build in a child process -- build.ps1 calls `exit` on completion, which - # would otherwise terminate the host process running this test file. - & pwsh -NoProfile -File '.\build.ps1' -Task Build - if ($LASTEXITCODE -ne 0) { - throw 'Failed to build PSKoans before running tests.' - } - Set-BuildEnvironment -Force - } - $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest - $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' - $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName - $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion - $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" - $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath - - # Remove all versions of the module from the session. Pester can't handle multiple versions. - Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore - Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop -} - -Describe 'Update-PSKoan' { - - Context 'Mocked Commands' { - - BeforeAll { - Mock 'Remove-Item' -ModuleName 'PSKoans' - Mock 'Copy-Item' -ModuleName 'PSKoans' - Mock 'New-Item' -ModuleName 'PSKoans' - Mock 'Move-Item' -ModuleName 'PSKoans' - Mock 'Update-PSKoanFile' -ModuleName 'PSKoans' - - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' -MockWith { - [PSCustomObject]@{ - Topic = 'Missing' - Path = 'Module\Group\AboutSomethingMissing.Koans.ps1' - } - [PSCustomObject]@{ - Topic = 'IncorrectPath' - Path = 'Module\Group\AboutSomethingIncorrectPath.Koans.ps1' - } - [PSCustomObject]@{ - Topic = 'Existing' - Path = 'Module\Group\AboutSomethingExisting.Koans.ps1' - } - } - - Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -ModuleName 'PSKoans' -MockWith { - [PSCustomObject]@{ - Topic = 'IncorrectPath' - Path = 'Module\RetiredGroup\AboutSomethingIncorrectPath.Koans.ps1' - } - [PSCustomObject]@{ - Topic = 'RetiredTopic' - Path = 'Module\RetiredGroup\AboutSomethingRetiredTopic.Koans.ps1' - } - [PSCustomObject]@{ - Topic = 'Existing' - Path = 'Module\Group\AboutSomethingExisting.Koans.ps1' - } - } - } - - It 'should not produce output' { - Update-PSKoan -Confirm:$false | Should -BeNullOrEmpty - } - - It 'should copy missing topic files' { - Should -Invoke 'Copy-Item' -Times 1 -Scope Context -ModuleName 'PSKoans' - } - - It 'should move incorrectly placed topics' { - Should -Invoke 'Remove-Item' -Times 1 -Scope Context -ModuleName 'PSKoans' - } - - It 'should remove discarded topics' { - Should -Invoke 'Remove-Item' -Times 1 -Scope Context -ModuleName 'PSKoans' - } - - It 'should update topics which exist in module and koan path' { - Should -Invoke 'Update-PSKoanFile' -ModuleName 'PSKoans' -Times 2 -Scope Context - } - } - - Context 'Practical Tests with TestDrive' { - - BeforeAll { - $koanLocation = Join-Path -Path $TestDrive -ChildPath 'PSKoans' - Mock 'Get-PSKoanLocation' -ModuleName 'PSKoans' { $koanLocation } - - New-Item -Path $koanLocation -ItemType Directory - Update-PSKoan -Confirm:$false - - $file = Get-ChildItem -Path $koanLocation -Filter *.koans.ps1 -File -Recurse | - Select-Object -First 1 - } - - It 'should copy missing topic files' { - $file | Remove-Item - $file.FullName | Should -Not -Exist - - Update-PSKoan -Confirm:$false - - $file.FullName | Should -Exist - } - - It 'should move incorrectly placed topics' { - $directory = New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'PSKoans\Wrong') -ItemType Directory - $file | Move-Item -Destination $directory.FullName - $file.FullName | Should -Not -Exist - - Update-PSKoan -Confirm:$false - - $file.FullName | Should -Exist - } - - It 'should remove discarded topics' { - $oldTopicPath = Join-Path $TestDrive 'PSKoans\Foundations\OldTopic.koans.ps1' - $file | Copy-Item -Destination $oldTopicPath - $oldTopicPath | Should -Exist - - Update-PSKoan -Confirm:$false - - $oldTopicPath | Should -Not -Exist - } - } -} +#Requires -Module @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } + +BeforeDiscovery { + if ($null -eq $env:BHProjectName) { + # Run the build in a child process -- build.ps1 calls `exit` on completion, which + # would otherwise terminate the host process running this test file. + & pwsh -NoProfile -File '.\build.ps1' -Task Build + if ($LASTEXITCODE -ne 0) { + throw 'Failed to build PSKoans before running tests.' + } + Set-BuildEnvironment -Force + } + $manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest + $outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output' + $outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName + $outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion + $outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1" + $env:PSModulePath = $outputModDir + [IO.Path]::PathSeparator + $env:PSModulePath + + # Remove all versions of the module from the session. Pester can't handle multiple versions. + Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore + Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop +} + +Describe 'Update-PSKoan' { + + Context 'Mocked Commands' { + + BeforeAll { + Mock 'Remove-Item' -ModuleName 'PSKoans' + Mock 'Copy-Item' -ModuleName 'PSKoans' + Mock 'New-Item' -ModuleName 'PSKoans' + Mock 'Move-Item' -ModuleName 'PSKoans' + Mock 'Update-PSKoanFile' -ModuleName 'PSKoans' + + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'Module' } -ModuleName 'PSKoans' -MockWith { + [PSCustomObject]@{ + Topic = 'Missing' + Path = 'Module\Group\AboutSomethingMissing.Koans.ps1' + } + [PSCustomObject]@{ + Topic = 'IncorrectPath' + Path = 'Module\Group\AboutSomethingIncorrectPath.Koans.ps1' + } + [PSCustomObject]@{ + Topic = 'Existing' + Path = 'Module\Group\AboutSomethingExisting.Koans.ps1' + } + } + + Mock 'Get-PSKoan' -ParameterFilter { $Scope -eq 'User' } -ModuleName 'PSKoans' -MockWith { + [PSCustomObject]@{ + Topic = 'IncorrectPath' + Path = 'Module\RetiredGroup\AboutSomethingIncorrectPath.Koans.ps1' + } + [PSCustomObject]@{ + Topic = 'RetiredTopic' + Path = 'Module\RetiredGroup\AboutSomethingRetiredTopic.Koans.ps1' + } + [PSCustomObject]@{ + Topic = 'Existing' + Path = 'Module\Group\AboutSomethingExisting.Koans.ps1' + } + } + } + + It 'should not produce output' { + Update-PSKoan -Confirm:$false | Should -BeNullOrEmpty + } + + It 'should copy missing topic files' { + Should -Invoke 'Copy-Item' -Times 1 -Scope Context -ModuleName 'PSKoans' + } + + It 'should move incorrectly placed topics' { + Should -Invoke 'Remove-Item' -Times 1 -Scope Context -ModuleName 'PSKoans' + } + + It 'should remove discarded topics' { + Should -Invoke 'Remove-Item' -Times 1 -Scope Context -ModuleName 'PSKoans' + } + + It 'should update topics which exist in module and koan path' { + Should -Invoke 'Update-PSKoanFile' -ModuleName 'PSKoans' -Times 2 -Scope Context + } + } + + Context 'Practical Tests with TestDrive' { + + BeforeAll { + $koanLocation = Join-Path -Path $TestDrive -ChildPath 'PSKoans' + Mock 'Get-PSKoanLocation' -ModuleName 'PSKoans' { $koanLocation } + + New-Item -Path $koanLocation -ItemType Directory + Update-PSKoan -Confirm:$false + + $file = Get-ChildItem -Path $koanLocation -Filter *.koans.ps1 -File -Recurse | + Select-Object -First 1 + } + + It 'should copy missing topic files' { + $file | Remove-Item + $file.FullName | Should -Not -Exist + + Update-PSKoan -Confirm:$false + + $file.FullName | Should -Exist + } + + It 'should move incorrectly placed topics' { + $directory = New-Item -Path (Join-Path -Path $TestDrive -ChildPath 'PSKoans\Wrong') -ItemType Directory + $file | Move-Item -Destination $directory.FullName + $file.FullName | Should -Not -Exist + + Update-PSKoan -Confirm:$false + + $file.FullName | Should -Exist + } + + It 'should remove discarded topics' { + $oldTopicPath = Join-Path $TestDrive 'PSKoans\Foundations\OldTopic.koans.ps1' + $file | Copy-Item -Destination $oldTopicPath + $oldTopicPath | Should -Exist + + Update-PSKoan -Confirm:$false + + $oldTopicPath | Should -Not -Exist + } + } +} diff --git a/Tests/KoanValidation.Tests.ps1 b/tests/KoanValidation.Tests.ps1 similarity index 100% rename from Tests/KoanValidation.Tests.ps1 rename to tests/KoanValidation.Tests.ps1 diff --git a/Tests/ModuleHelp.Tests.ps1 b/tests/ModuleHelp.Tests.ps1 similarity index 100% rename from Tests/ModuleHelp.Tests.ps1 rename to tests/ModuleHelp.Tests.ps1 diff --git a/Tests/ModuleValidation.Tests.ps1 b/tests/ModuleValidation.Tests.ps1 similarity index 100% rename from Tests/ModuleValidation.Tests.ps1 rename to tests/ModuleValidation.Tests.ps1