Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 10 additions & 22 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,19 @@
"version": "0.2.0",
"configurations": [
{
"name": "PowerShell Launch Current File",
"name": "PowerShell Launch Script",
"type": "PowerShell",
"request": "launch",
"script": "${file}",
"args": [],
"cwd": "${file}"
},
{
"name": "PowerShell Launch Current File in Temporary Console",
"type": "PowerShell",
"request": "launch",
"script": "${file}",
"args": [],
"cwd": "${file}",
"createTemporaryIntegratedConsole": true
"script": "./Start-DebugSession.ps1",
"cwd": "${workspaceFolder}"
},
{
"name": "PowerShell Launch Current File w/Args Prompt",
"name": "PowerShell: Launch Current File",
"type": "PowerShell",
"request": "launch",
"script": "${file}",
"args": [
"${command:SpecifyScriptArgs}"
],
"cwd": "${file}"
},
{
"name": "PowerShell Attach to Host Process",
"type": "PowerShell",
"request": "attach"
},
{
"name": "PowerShell Interactive Session",
"type": "PowerShell",
Expand All @@ -47,6 +29,12 @@
"type": "PowerShell",
"request": "attach",
"processId": "current"
},
{
"name": "PowerShell Attach to Host Process",
"type": "PowerShell",
"request": "attach",
"runspaceId": 1
}
]
}
48 changes: 40 additions & 8 deletions PSKoans/Private/Invoke-Koan.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,57 @@
)
end {
try {
$Requirements = [System.Management.Automation.Language.Parser]::ParseFile(
$ParameterSplat.Script,
[ref]$null,
[ref]$null
).Ast.ScriptRequirements

$Script = {
param( $Params )
param( $Params, $RequiredModules, $PSKoansPath, $PSModulePath )

[System.Collections.Generic.HashSet[string]] $ModulePaths = @(
$PSModulePath -split [System.IO.Path]::PathSeparator
$env:PSModulePath -split [System.IO.Path]::PathSeparator
)

$env:PSModulePath = $ModulePaths -join [System.IO.Path]::PathSeparator

Get-Module $PSKoansPath -ListAvailable | Import-Module
foreach ($module in $RequiredModules) {
Import-Module $module
}

. ([scriptblock]::Create('using module PSKoans'))
Invoke-Pester @Params
}

$Thread = [powershell]::Create()
$Thread.AddScript($Script) > $null
$Thread.AddArgument($ParameterSplat) > $null
$Runspace = [powershell]::Create()
$Runspace.AddScript($Script) > $null
$Runspace.AddParameter('Params', $ParameterSplat) > $null
$Runspace.AddParameter('PSKoansPath', $MyInvocation.MyCommand.Module.ModuleBase) > $null
$Runspace.AddParameter('PSModulePath', $env:PSModulePath) > $null

$Status = $Thread.BeginInvoke()
if ($Requirements.RequiredModules) {
$Runspace.AddParameter('RequiredModules', $Requirements.RequiredModules)
}

$Status = $Runspace.BeginInvoke()

do { Start-Sleep -Milliseconds 1 } until ($Status.IsCompleted)

$Thread.EndInvoke($Status)
$Result = $Runspace.EndInvoke($Status)

if ($Runspace.HadErrors) {
# These will be errors outside the test itself; better propagate them upwards.
foreach ($errorItem in $Runspace.Streams.Error) {
$PSCmdlet.WriteError($errorItem)
}
}

$Result
}
finally {
$Thread.Dispose()
$Runspace.Dispose()
}
}
}
30 changes: 28 additions & 2 deletions PSKoans/Public/Get-Karma.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
'ListKoans' {
Get-PSKoan @GetParams
}
"Default" {
default {
Write-Verbose 'Sorting koans...'
try {
$SortedKoanList = Get-PSKoan @GetParams
Expand All @@ -46,6 +46,17 @@
$PSCmdlet.ThrowTerminatingError($_)
}

foreach ($item in $IncludeModule) {
if ($SortedKoanList.Where{ $_.Module -notlike $item }.Count -eq 0) {
$warningString = @(
"Koans for a module name matching '$item' were not found in your user directory."
"Please run Update-PSKoan -Module $item to ensure those modules are present."
) -join ' '

Write-Warning $warningString
}
}

Write-Verbose "Koan files retrieved: $($SortedKoanList.Count)"
Write-Verbose 'Counting koans...'
[int]$TotalKoans = $SortedKoanList | Measure-Koan
Expand All @@ -68,9 +79,24 @@
$PSCmdlet.ThrowTerminatingError( (New-PSKoanErrorRecord @ErrorDetails) )
}

if ($Module) {
# No koans were found because modules aren't copied by default.
Update-PSKoan -Module $Module -Confirm:$false
Get-Karma @PSBoundParameters

return
}

# Something's wrong; possibly a koan folder from older versions, or a folder exists but has no files
$Modules = if ($IncludeModule) {
@{ IncludeModule = $IncludeModule }
}
else {
@{ }
}

Write-Warning 'No koans found in your koan directory. Initiating full reset...'
Update-PSKoan -Confirm:$false
Update-PSKoan -Confirm:$false @Modules
Get-Karma @PSBoundParameters # Re-call ourselves with the same parameters

return # Skip the rest of the function
Expand Down
24 changes: 15 additions & 9 deletions PSKoans/Public/Get-PSKoan.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,31 @@ function Get-PSKoan {
'Module' { Join-Path -Path $script:ModuleRoot -ChildPath 'Koans' }
}

if ($pscmdlet.ParameterSetName -eq 'ListModules') {
$moduleList = Join-Path -Path $ParentPath -ChildPath 'Modules' |
Get-ChildItem -Directory |
Select-Object -ExpandProperty Name
if ($PSCmdlet.ParameterSetName -eq 'ListModules') {
$modulesPath = Join-Path -Path $ParentPath -ChildPath 'Modules'

return $moduleList
if (Test-Path $modulesPath) {
$modulesPath |
Get-ChildItem -Directory |
Select-Object -ExpandProperty Name
}

return
}

$KoanDirectories = switch ($pscmdlet.ParameterSetName) {
$KoanDirectories = switch ($PSCmdlet.ParameterSetName) {
'IncludeModule' {
$Module = $IncludeModule
Get-ChildItem $ParentPath -Exclude Modules -Directory
}
{ $Module } {
$ModuleRegex = ConvertFrom-WildcardPattern -Pattern $Module

Join-Path -Path $ParentPath -ChildPath 'Modules' |
Get-ChildItem -Directory |
Where-Object { $_.Name -match $ModuleRegex }
$modulesPath = Join-Path -Path $ParentPath -ChildPath 'Modules'
if (Test-Path $modulesPath) {
Get-ChildItem $modulesPath -Directory |
Where-Object { $_.Name -match $ModuleRegex }
}
}
}

Expand Down
31 changes: 23 additions & 8 deletions PSKoans/Public/Show-Karma.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,43 @@ function Show-Karma {
[Alias('Invoke-PSKoans', 'Test-Koans', 'Get-Enlightenment', 'Meditate', 'Clear-Path', 'Measure-Karma')]
param(
[Parameter(ParameterSetName = 'ListKoans')]
[Parameter(ParameterSetName = 'ListKoans-ModuleOnly')]
[Parameter(ParameterSetName = 'ListKoans-IncludeModule')]
[Parameter(ParameterSetName = 'ModuleOnly')]
[Parameter(ParameterSetName = 'IncludeModule')]
[Parameter(ParameterSetName = 'OpenFile')]
[Parameter(ParameterSetName = 'OpenFile-ModuleOnly')]
[Parameter(ParameterSetName = 'OpenFile-IncludeModule')]
[Parameter(ParameterSetName = 'Default')]
[Alias('Koan', 'File')]
[SupportsWildcards()]
[string[]]
$Topic,

[Parameter(Mandatory, ParameterSetName = 'ModuleOnly')]
[Parameter(ParameterSetName = 'ListKoans')]
[Parameter(Mandatory, ParameterSetName = 'ListKoans-ModuleOnly')]
[Parameter(Mandatory, ParameterSetName = 'OpenFile-ModuleOnly')]
[SupportsWildcards()]
[string[]]
$Module,

[Parameter(Mandatory, ParameterSetName = 'IncludeModule')]
[Parameter(Mandatory, ParameterSetName = 'ListKoans-IncludeModule')]
[Parameter(Mandatory, ParameterSetName = 'OpenFile-IncludeModule')]
[SupportsWildcards()]
[string[]]
$IncludeModule,

[Parameter(Mandatory, ParameterSetName = 'ListKoans')]
[Parameter(Mandatory, ParameterSetName = 'ListKoans-ModuleOnly')]
[Parameter(Mandatory, ParameterSetName = 'ListKoans-IncludeModule')]
[Alias('ListKoans', 'ListTopics')]
[switch]
$List,

[Parameter(Mandatory, ParameterSetName = 'OpenFile')]
[Parameter(Mandatory, ParameterSetName = 'OpenFile-ModuleOnly')]
[Parameter(Mandatory, ParameterSetName = 'OpenFile-IncludeModule')]
[Alias('Meditate')]
[switch]
$Contemplate,
Expand All @@ -55,13 +66,13 @@ function Show-Karma {

$GetParams = @{ }
switch ($PSCmdlet.ParameterSetName) {
'IncludeModule' { $GetParams['IncludeModule'] = $IncludeModule }
'ModuleOnly' { $GetParams['Module'] = $Module }
{ $_ -match 'IncludeModule$' } { $GetParams['IncludeModule'] = $IncludeModule }
{ $_ -match 'ModuleOnly$' } { $GetParams['Module'] = $Module }
{ $PSBoundParameters.ContainsKey('Topic') } { $GetParams['Topic'] = $Topic }
}

switch ($PSCmdlet.ParameterSetName) {
'ListKoans' {
{ $_ -match '^ListKoans' } {
Get-PSKoan @GetParams
}
'OpenFolder' {
Expand All @@ -86,7 +97,7 @@ function Show-Karma {
$KoanLocation | Invoke-Item
}
}
'OpenFile' {
{ $_ -match '^OpenFile' } {
# If there is no cached data, we need to call Get-Karma to populate it
if (-not $script:CurrentTopic -or ($Topic -and $script:CurrentTopic.Name -notlike $Topic)) {
try {
Expand All @@ -99,7 +110,12 @@ function Show-Karma {
}

$Editor = Get-PSKoanSetting -Name Editor
$FilePath = (Get-PSKoan -Topic $script:CurrentTopic.Name -Scope User).Path
$KoanParams = @{
Topic = $script:CurrentTopic.Name
IncludeModule = @( $Module; $IncludeModule )
Scope = 'User'
}
$FilePath = (Get-PSKoan @KoanParams).Path
$LineNumber = $script:CurrentTopic.CurrentLine

$Arguments = switch ($Editor) {
Expand Down Expand Up @@ -140,8 +156,7 @@ function Show-Karma {
try {
Get-Karma @GetParams |
Format-Custom @FormatParams |
Out-String |
Write-Host
Out-Host
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
Expand Down
11 changes: 11 additions & 0 deletions Start-DebugSession.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
$env:PSModulePath = $(
@(
$env:PSModulePath -split [System.IO.Path]::PathSeparator
$PSScriptRoot
) | Select-Object -Unique
) -join [System.IO.Path]::PathSeparator

& $PSScriptRoot/PSKoans.ezformat.ps1
Import-Module $PSScriptRoot/PSKoans

### Enter code to test below
16 changes: 8 additions & 8 deletions Tests/Functions/Public/Show-Karma.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Describe 'Show-Karma' {

Context 'Default Behaviour' {
BeforeAll {
Mock Write-Host { }
Mock Out-Host { }
Mock Get-Karma -ModuleName 'PSKoans' {
[PSCustomObject]@{
PSTypeName = 'PSKoans.Result'
Expand All @@ -50,7 +50,7 @@ Describe 'Show-Karma' {
}

It 'should write the formatted output to host' {
Assert-MockCalled Write-Host
Assert-MockCalled Out-Host
}

It 'should call Get-Karma to examine the koans' {
Expand All @@ -60,7 +60,7 @@ Describe 'Show-Karma' {

Context 'With All Koans Completed' {
BeforeAll {
Mock Write-Host { }
Mock Out-Host { }
Mock Get-Karma -ModuleName 'PSKoans' {
[PSCustomObject]@{
PSTypeName = 'PSKoans.CompleteResult'
Expand All @@ -80,7 +80,7 @@ Describe 'Show-Karma' {
Context 'With -ClearScreen Switch' {
BeforeAll {
Mock Clear-Host { }
Mock Write-Host { }
Mock Out-Host { }
Mock Get-Karma -ModuleName 'PSKoans' {
[PSCustomObject]@{
PSTypeName = 'PSKoans.Result'
Expand Down Expand Up @@ -109,7 +109,7 @@ Describe 'Show-Karma' {
}

It 'should display the rendered output' {
Assert-MockCalled Write-Host
Assert-MockCalled Out-Host
}

It 'should Invoke-Pester on each of the koans' {
Expand All @@ -119,7 +119,7 @@ Describe 'Show-Karma' {

Context 'With Nonexistent Koans Folder / No Koans Found' {
BeforeAll {
Mock Write-Host { }
Mock Out-Host { }
Mock Get-PSKoan -ModuleName 'PSKoans' { }
Mock Update-PSKoan -ModuleName 'PSKoans' { throw 'Prevent recursion' }
Mock Write-Warning
Expand Down Expand Up @@ -174,7 +174,7 @@ Describe 'Show-Karma' {

Context 'With -Topic Parameter' {
BeforeAll {
Mock Write-Host { }
Mock Out-Host { }
Mock Get-Karma -MockWith {
[PSCustomObject]@{
PSTypeName = 'PSKoans.Result'
Expand Down Expand Up @@ -204,7 +204,7 @@ Describe 'Show-Karma' {
Context 'With All Koans in a Single Topic Completed' {
BeforeAll {
Mock Format-Custom { $InputObject.Complete }
Mock Write-Host { }
Mock Out-Host { }
Mock Get-Karma -ModuleName 'PSKoans' {
[PSCustomObject]@{
PSTypeName = 'PSKoans.CompleteResult'
Expand Down