From 509c05b6ccd3d5ee90b2e15218345c92cbbce44b Mon Sep 17 00:00:00 2001 From: Frederic Gagnon Date: Thu, 11 Apr 2024 08:28:07 -0400 Subject: [PATCH] Allow using 'RootModule/NestedModule' as ModuleName --- src/functions/InModuleScope.ps1 | 7 ++++- tst/functions/InModuleScope.Tests.ps1 | 45 ++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/functions/InModuleScope.ps1 b/src/functions/InModuleScope.ps1 index 9b9066b43..e26ae9b41 100644 --- a/src/functions/InModuleScope.ps1 +++ b/src/functions/InModuleScope.ps1 @@ -176,7 +176,12 @@ function Get-CompatibleModule { if ($PesterPreference.Debug.WriteDebugMessages.Value) { Write-PesterDebugMessage -Scope Runtime "Searching for a module $ModuleName." } - $modules = @(& $SafeCommands['Get-Module'] -Name $ModuleName -All -ErrorAction Stop) + if ($ModuleName -match '(?\w+)[/\\](?\w+)') { + $modules = @(& $SafeCommands['Get-Module'] -Name $Matches['RootModule'] -All -ErrorAction Stop | & $SafeCommands['Select-Object'] -ExpandProperty NestedModules | & $SafeCommands['Where-Object'] { $_.Name -eq $Matches['NestedModule'] }) + } + else { + $modules = @(& $SafeCommands['Get-Module'] -Name $ModuleName -All -ErrorAction Stop) + } } catch { throw "No modules named '$ModuleName' are currently loaded." diff --git a/tst/functions/InModuleScope.Tests.ps1 b/tst/functions/InModuleScope.Tests.ps1 index 9f3f74fd1..6e144487c 100644 --- a/tst/functions/InModuleScope.Tests.ps1 +++ b/tst/functions/InModuleScope.Tests.ps1 @@ -125,6 +125,49 @@ Describe 'Get-CompatibleModule' { } } + Context 'when module name matches a root and a nested module' { + BeforeAll { + $nestedModuleName = 'NestedModule' + $moduleName = 'RootWithNestedModule' + $moduleManifestPath = "TestDrive:/$moduleName.psd1" + New-Item -Path "TestDrive:/$nestedModuleName.psm1" -ItemType File -Force -ErrorAction Stop | Out-Null + '[string]$Script:ModuleVar = "Foo"' | Out-File -FilePath "TestDrive:/$nestedModuleName.psm1" -Encoding ascii + New-ModuleManifest -Path $moduleManifestPath -NestedModules ".\$nestedModuleName.psm1" + Import-Module $moduleManifestPath -Force + } + + AfterAll { + Get-Module $moduleName -ErrorAction SilentlyContinue | Remove-Module -Force + } + + It 'should return a single ModuleInfo object when using a slash as delimiter' { + $moduleInfo = InPesterModuleScope { Get-CompatibleModule -ModuleName 'RootWithNestedModule/NestedModule' } + $moduleInfo | Should -Not -BeNullOrEmpty + @($moduleInfo).Count | Should -Be 1 + $moduleInfo.Name | Should -Be 'NestedModule' + $moduleInfo.ModuleType | Should -Be 'Script' + } + + It 'should return a single ModuleInfo object when using a backslash as delimiter' { + $moduleInfo = InPesterModuleScope { Get-CompatibleModule -ModuleName 'RootWithNestedModule\NestedModule' } + $moduleInfo | Should -Not -BeNullOrEmpty + @($moduleInfo).Count | Should -Be 1 + $moduleInfo.Name | Should -Be 'NestedModule' + $moduleInfo.ModuleType | Should -Be 'Script' + } + + It 'should return the module session state name' { + $name = InModuleScope -ModuleName 'RootWithNestedModule\NestedModule' -ScriptBlock { $ExecutionContext.SessionState.Module.Name } + $name | Should -Be 'NestedModule' + } + + It 'should return a nested module variable value' { + InModuleScope -ModuleName 'RootWithNestedModule\NestedModule' -ScriptBlock { + $Script:ModuleVar | Should -Be 'Foo' + } + } + } + } Describe 'InModuleScope arguments and parameter binding' { @@ -340,4 +383,4 @@ Describe 'Working with manifest modules' { $res = InModuleScope -ModuleName $moduleName -ScriptBlock { myPrivateFunction } $res | Should -Be 'real' } -} \ No newline at end of file +}