Skip to content

Commit 7f077f5

Browse files
committed
feat(tests): ✨ Add DotSource.psm1 for testing module functionality
* Introduced a new `DotSource.psm1` file to facilitate testing of dot-sourced public functions. * This file includes logic to import both public and private functions for comprehensive testing.
1 parent 7ad41e9 commit 7f077f5

File tree

2 files changed

+101
-30
lines changed

2 files changed

+101
-30
lines changed

tests/build.tests.ps1

Lines changed: 89 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,67 @@
11
# spell-checker:ignore excludeme
2+
BeforeDiscovery {
3+
if ($null -eq $env:BHProjectPath) {
4+
$path = Join-Path -Path $PSScriptRoot -ChildPath '..\build.ps1'
5+
. $path -Task Build
6+
}
7+
$manifest = Import-PowerShellDataFile -Path $env:BHPSModuleManifest
8+
$outputDir = Join-Path -Path $env:BHProjectPath -ChildPath 'Output'
9+
$outputModDir = Join-Path -Path $outputDir -ChildPath $env:BHProjectName
10+
$outputModVerDir = Join-Path -Path $outputModDir -ChildPath $manifest.ModuleVersion
11+
$global:outputModVerManifest = Join-Path -Path $outputModVerDir -ChildPath "$($env:BHProjectName).psd1"
12+
13+
# Get module commands
14+
# Remove all versions of the module from the session. Pester can't handle multiple versions.
15+
Get-Module $env:BHProjectName | Remove-Module -Force -ErrorAction Ignore
16+
Import-Module -Name $outputModVerManifest -Verbose:$false -ErrorAction Stop
17+
}
218
Describe 'Build' {
3-
419
BeforeAll {
5-
$tempDir = Join-Path $TestDrive 'TestModule'
6-
Copy-Item $PSScriptRoot/fixtures/TestModule $tempDir -Recurse
7-
Push-Location $tempDir
20+
<#
21+
We prepare the tests by copying the TestModule to a temporary location
22+
and setting the output path to a known location.
23+
#>
24+
25+
$script:testModuleSource = Join-Path $TestDrive 'TestModule'
26+
Copy-Item $PSScriptRoot/fixtures/TestModule $script:testModuleSource -Recurse
27+
Set-Location $script:testModuleSource
28+
# Hack for GH Actions
29+
# For some reason, the TestModule build process create the output in the project root
30+
# and not relative to it's own build file.
31+
if ($env:GITHUB_ACTION) {
32+
$script:testModuleOutputPath = [IO.Path]::Combine($env:BHProjectPath, 'Output', 'TestModule', '0.1.0')
33+
} else {
34+
$script:testModuleOutputPath = [IO.Path]::Combine($script:testModuleSource, 'Output', 'TestModule', '0.1.0')
35+
}
836

937
# Capture any of the jobs for cleanup later
1038
[array]$script:jobs = @()
11-
12-
$path = 'Output/TestModule/0.1.0'
13-
$script:testModuleOutputPath = Join-Path $tempDir $path
1439
}
1540

1641
AfterAll {
17-
Pop-Location
18-
$jobs | Stop-Job -ErrorAction Ignore
19-
$jobs | Remove-Job -ErrorAction Ignore
42+
Set-Location $PSScriptRoot
2043
}
2144

2245
Context 'Compile module' {
2346
BeforeAll {
24-
Write-Host "PSScriptRoot: $tempDir"
47+
Write-Host "PSScriptRoot: $script:testModuleSource"
2548
Write-Host "OutputPath: $script:testModuleOutputPath"
2649

2750
# build is PS job so psake doesn't freak out because it's nested
2851
$script:jobs += Start-Job -Scriptblock {
29-
Set-Location $using:tempDir
52+
param($testModuleSource, $outputModVerManifest)
53+
Set-Location -Path $using:testModuleSource
54+
# We want to load the current build of PowerShellBuild so we use a
55+
# global variable to store the output path.
56+
$global:PSBOutput = $outputModVerManifest
3057
$global:PSBuildCompile = $true
3158
./build.ps1 -Task Build
32-
} -WorkingDirectory $script:testModuleSource | Wait-Job
59+
} -WorkingDirectory $script:testModuleSource -ArgumentList $testModuleSource, $outputModVerManifest | Wait-Job
3360
}
34-
3561
AfterAll {
3662
Remove-Item $script:testModuleOutputPath -Recurse -Force
63+
$jobs | Stop-Job -ErrorAction Ignore
64+
$jobs | Remove-Job -ErrorAction Ignore
3765
}
3866

3967
It 'Creates module' {
@@ -76,22 +104,28 @@ Describe 'Build' {
76104

77105
Context 'Dot-sourced module' {
78106
BeforeAll {
107+
$copyItemSplat = @{
108+
Path = "$PSScriptRoot/fixtures/DotSource.psm1"
109+
Destination = "$script:testModuleSource/TestModule/TestModule.psm1"
110+
Force = $true
111+
}
112+
# Overwrite the existing PSM1 with the dot-sourced version
113+
Copy-Item @copyItemSplat
79114
# build is PS job so psake doesn't freak out because it's nested
80115
$script:jobs += Start-Job -Scriptblock {
81-
Set-Location $using:tempDir
116+
param($testModuleSource, $outputModVerManifest)
117+
Set-Location -Path $testModuleSource
118+
# We want to load the current build of PowerShellBuild so we use a
119+
# global variable to store the output path.
120+
$global:PSBOutput = $outputModVerManifest
82121
$global:PSBuildCompile = $false
83122
./build.ps1 -Task Build
84-
} -WorkingDirectory $script:testModuleSource | Wait-Job
85-
Write-Debug "TestModule output path: $script:testModuleSource"
86-
$items = Get-ChildItem -Path $script:testModuleSource -Recurse -File
87-
Write-Debug ($items | Format-Table FullName | Out-String)
88-
Write-Debug "TestModule output path: $script:testModuleOutputPath"
89-
$items = Get-ChildItem -Path $script:testModuleOutputPath -Recurse -File
90-
Write-Debug ($items | Format-Table FullName | Out-String)
123+
} -WorkingDirectory $script:testModuleSource -ArgumentList $testModuleSource, $outputModVerManifest | Wait-Job
91124
}
92-
93125
AfterAll {
94126
Remove-Item $script:testModuleOutputPath -Recurse -Force
127+
$jobs | Stop-Job -ErrorAction Ignore
128+
$jobs | Remove-Job -ErrorAction Ignore
95129
}
96130

97131
It 'Creates module' {
@@ -112,38 +146,63 @@ Describe 'Build' {
112146
}
113147

114148
It 'Has MAML help XML' {
115-
"$script:testModuleOutputPath/en-US/TestModule-help.xml" | Should -Exist
149+
[IO.Path]::Combine($script:testModuleOutputPath, "en-US", "TestModule-help.xml") | Should -Exist
116150
}
117151
}
118152
Context 'Overwrite Docs' {
119153
BeforeAll {
120154

121-
Write-Host "PSScriptRoot: $tempDir"
155+
Write-Host "PSScriptRoot: $script:testModuleSource"
122156
Write-Host "OutputPath: $script:testModuleOutputPath"
123157

158+
$copyItemSplat = @{
159+
Path = "$PSScriptRoot/fixtures/DotSource.psm1"
160+
Destination = "$script:testModuleSource/TestModule/TestModule.psm1"
161+
Force = $true
162+
}
163+
# Overwrite the existing PSM1 with the dot-sourced version
164+
Copy-Item @copyItemSplat
165+
# Build once, and then we'll modify
166+
$script:jobs += Start-Job -Scriptblock {
167+
param($testModuleSource, $outputModVerManifest)
168+
Set-Location -Path $using:testModuleSource
169+
# We want to load the current build of PowerShellBuild so we use a
170+
# global variable to store the output path.
171+
$global:PSBOutput = $global:outputModVerManifest
172+
$global:PSBuildCompile = $false
173+
./build.ps1 -Task Build
174+
} -WorkingDirectory $script:testModuleSource -ArgumentList $testModuleSource, $outputModVerManifest | Wait-Job
175+
124176
# Replace with a different string to test the overwrite
125-
$script:docPath = "$tempDir/docs/en-US/Get-HelloWorld.md"
177+
$script:docPath = [IO.Path]::Combine($script:testModuleSource, "docs", "en-US", "Get-HelloWorld.md")
126178
$script:original = Get-Content $docPath -Raw
127179
$new = $original -replace 'Hello World', 'Hello Universe'
128180
Set-Content $docPath -Value $new -Force
129181

130182
# Update the psake file
131-
$psakeFile = "$tempDir/psakeFile.ps1"
183+
$psakeFile = [IO.Path]::Combine($script:testModuleSource, "psakeFile.ps1")
132184
$psakeFileContent = Get-Content $psakeFile -Raw
133185
$psakeFileContent = $psakeFileContent -replace '\$PSBPreference.Docs.Overwrite = \$false', '$PSBPreference.Docs.Overwrite = $true'
134186
Set-Content $psakeFile -Value $psakeFileContent -Force
135187

136188
# build is PS job so psake doesn't freak out because it's nested
137189
$script:jobs += Start-Job -Scriptblock {
138-
Set-Location $using:tempDir
139-
$global:PSBuildCompile = $true
190+
param($testModuleSource, $outputModVerManifest)
191+
Set-Location -Path $using:testModuleSource
192+
# We want to load the current build of PowerShellBuild so we use a
193+
# global variable to store the output path.
194+
$global:PSBOutput = $global:outputModVerManifest
195+
$global:PSBuildCompile = $false
140196
./build.ps1 -Task Build
141-
} | Wait-Job
197+
} -WorkingDirectory $script:testModuleSource -ArgumentList $testModuleSource, $outputModVerManifest | Wait-Job
142198
}
143199

144200
AfterAll {
145201
Remove-Item $script:testModuleOutputPath -Recurse -Force
202+
$jobs | Stop-Job -ErrorAction Ignore
203+
$jobs | Remove-Job -ErrorAction Ignore
146204
}
205+
147206
It 'Can Overwrite the Docs' {
148207
# Test that the file reset as expected
149208
Get-Content $script:docPath -Raw | Should -BeExactly $script:original

tests/fixtures/DotSource.psm1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# This is what a non compiled psm1 would look like. We use this for some of the tests
2+
# Dot source public functions
3+
$private = @(Get-ChildItem -Path ([IO.Path]::Combine($PSScriptRoot, 'Private/*.ps1')) -Recurse)
4+
$public = @(Get-ChildItem -Path ([IO.Path]::Combine($PSScriptRoot, 'Public/*.ps1')) -Recurse)
5+
foreach ($import in $public + $private) {
6+
try {
7+
. $import.FullName
8+
} catch {
9+
throw "Unable to dot source [$($import.FullName)]"
10+
}
11+
}
12+
Export-ModuleMember -Function $public.Basename

0 commit comments

Comments
 (0)