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
87 changes: 87 additions & 0 deletions tests/Fixtures.tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
BeforeAll {
Import-Module -Name ([IO.Path]::Combine($PSScriptRoot, 'fixtures', 'FixtureHelpers.psm1')) -Force
}

AfterAll {
Remove-Module -Name 'FixtureHelpers' -Force -ErrorAction SilentlyContinue
}

Describe 'PSBuildTestFixture' {

Context 'Copy helper' {

It 'Copies the fixture into the destination and returns the copy path' {
$fixturePath = Copy-PSBuildTestFixture -Destination $TestDrive

$fixturePath | Should -Be (Join-Path -Path $TestDrive -ChildPath 'PSBuildTestFixture')
$fixturePath | Should -Exist
}

It 'Copies the complete fixture layout' {
$fixturePath = Copy-PSBuildTestFixture -Destination (Join-Path -Path $TestDrive -ChildPath 'layout')

Join-Path -Path $fixturePath -ChildPath 'PSBuildTestFixture.psd1' | Should -Exist
Join-Path -Path $fixturePath -ChildPath 'PSBuildTestFixture.psm1' | Should -Exist
Join-Path -Path $fixturePath -ChildPath 'Public/Get-Widget.ps1' | Should -Exist
Join-Path -Path $fixturePath -ChildPath 'Public/Set-Widget.ps1' | Should -Exist
Join-Path -Path $fixturePath -ChildPath 'Private/Test-WidgetName.ps1' | Should -Exist
Join-Path -Path $fixturePath -ChildPath 'excludeme.txt' | Should -Exist

Check warning on line 28 in tests/Fixtures.tests.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (excludeme) Suggestions: (exclude, excluded, excluder, excludes, excluders)
}

It 'Recopying into the same destination replaces the copy without nesting' {
$destination = Join-Path -Path $TestDrive -ChildPath 'recopy'
$firstCopyPath = Copy-PSBuildTestFixture -Destination $destination
$secondCopyPath = Copy-PSBuildTestFixture -Destination $destination

$secondCopyPath | Should -Be $firstCopyPath
Join-Path -Path $secondCopyPath -ChildPath 'PSBuildTestFixture.psd1' | Should -Exist
Join-Path -Path $secondCopyPath -ChildPath 'PSBuildTestFixture' | Should -Not -Exist
}
}

Context 'Fixture module' {

BeforeAll {
$script:fixturePath = Copy-PSBuildTestFixture -Destination (Join-Path -Path $TestDrive -ChildPath 'module')
$script:fixtureManifestPath = Join-Path -Path $script:fixturePath -ChildPath 'PSBuildTestFixture.psd1'
}

AfterAll {
Remove-Module -Name 'PSBuildTestFixture' -Force -ErrorAction SilentlyContinue
}

It 'Has a valid module manifest' {
{ Test-ModuleManifest -Path $script:fixtureManifestPath -ErrorAction Stop } | Should -Not -Throw
}

It 'Imports from a test drive copy' {
{ Import-Module -Name $script:fixtureManifestPath -Force -ErrorAction Stop } | Should -Not -Throw
}

It 'Exports exactly the two public functions' {
$exportedCommands = (Get-Module -Name 'PSBuildTestFixture').ExportedFunctions.Keys | Sort-Object
$exportedCommands | Should -Be @('Get-Widget', 'Set-Widget')
}

It 'Does not export the private helper' {
(Get-Module -Name 'PSBuildTestFixture').ExportedFunctions.Keys | Should -Not -Contain 'Test-WidgetName'
}

It 'Public functions work end to end' {
$widget = Get-Widget -Name 'Sprocket' -Quantity 5

$widget.Name | Should -Be 'Sprocket'
$widget.Quantity | Should -Be 5
}

It 'Public functions have complete comment-based help' -ForEach @('Get-Widget', 'Set-Widget') {
$help = Get-Help -Name $_ -Full

$help.Synopsis | Should -Not -BeNullOrEmpty
$help.Description | Should -Not -BeNullOrEmpty
# The array subexpression matters: on Windows PowerShell 5.1 a single help
# example is a bare PSObject whose .Count is $null.
@($help.Examples.Example).Count | Should -BeGreaterOrEqual 1
}
}
}
45 changes: 45 additions & 0 deletions tests/fixtures/FixtureHelpers.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
function Copy-PSBuildTestFixture {
<#
.SYNOPSIS
Copy the PSBuildTestFixture module to a destination directory.
.DESCRIPTION
Copies the checked-in PSBuildTestFixture module into the supplied destination (typically
$TestDrive) and returns the path of the copy. Tests must always operate on a copy so that
no test run ever mutates the checked-in fixture and every test starts from a pristine
fixture state.
.PARAMETER Destination
Directory to copy the fixture into. The copy is created as a PSBuildTestFixture
subdirectory of this path.
.EXAMPLE
PS> $fixturePath = Copy-PSBuildTestFixture -Destination $TestDrive

Copies the fixture module into the Pester test drive and returns the path of the copy.
.OUTPUTS
System.String
#>
[CmdletBinding()]
[OutputType([string])]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$Destination
)

$fixtureSourcePath = Join-Path -Path $PSScriptRoot -ChildPath 'PSBuildTestFixture'
$fixtureCopyPath = Join-Path -Path $Destination -ChildPath 'PSBuildTestFixture'

# Remove any previous copy and recreate the directory before copying the fixture
# contents. Copying into an existing directory would otherwise nest a second
# PSBuildTestFixture directory inside it, and the destination (or its parents)
# may not exist yet.
if (Test-Path -Path $fixtureCopyPath) {
Remove-Item -Path $fixtureCopyPath -Recurse -Force
}
New-Item -Path $fixtureCopyPath -ItemType Directory -Force > $null
Copy-Item -Path (Join-Path -Path $fixtureSourcePath -ChildPath '*') -Destination $fixtureCopyPath -Recurse -Force

$fixtureCopyPath
}

Export-ModuleMember -Function 'Copy-PSBuildTestFixture'
22 changes: 22 additions & 0 deletions tests/fixtures/PSBuildTestFixture/PSBuildTestFixture.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@{
RootModule = 'PSBuildTestFixture.psm1'
ModuleVersion = '0.1.0'
GUID = '1bc197fe-a274-4d34-965d-862f9a8fe7b7'
Author = 'psake contributors'
CompanyName = 'Community'
Copyright = '(c) psake contributors. All rights reserved.'
Description = 'Minimal fixture module consumed by the PowerShellBuild integration tests. Not published.'
PowerShellVersion = '5.1'
FunctionsToExport = @(
'Get-Widget'
'Set-Widget'
)
CmdletsToExport = @()
VariablesToExport = @()
AliasesToExport = @()
PrivateData = @{
PSData = @{
Tags = @('PowerShellBuild', 'TestFixture')
}
}
}
12 changes: 12 additions & 0 deletions tests/fixtures/PSBuildTestFixture/PSBuildTestFixture.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Dot source public and private functions
$private = @(Get-ChildItem -Path ([IO.Path]::Combine($PSScriptRoot, 'Private/*.ps1')) -Recurse)
$public = @(Get-ChildItem -Path ([IO.Path]::Combine($PSScriptRoot, 'Public/*.ps1')) -Recurse)
foreach ($import in $public + $private) {
try {
. $import.FullName
} catch {
throw "Unable to dot source [$($import.FullName)]: $($_.Exception.Message)"
}
}
Comment thread
Copilot marked this conversation as resolved.

Export-ModuleMember -Function $public.Basename
28 changes: 28 additions & 0 deletions tests/fixtures/PSBuildTestFixture/Private/Test-WidgetName.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function Test-WidgetName {
<#
.SYNOPSIS
Validate a widget name.
.DESCRIPTION
Returns $true when the widget name contains only letters, digits, and hyphens. This private
helper exists so the integration tests can assert that private functions are dot-sourced
into compiled output but never exported.
.PARAMETER Name
Widget name to validate.
.EXAMPLE
PS> Test-WidgetName -Name 'Sprocket'

Returns $true.
.OUTPUTS
System.Boolean
#>
[CmdletBinding()]
[OutputType([bool])]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$Name
)

$Name -match '^[A-Za-z0-9-]+$'
}
46 changes: 46 additions & 0 deletions tests/fixtures/PSBuildTestFixture/Public/Get-Widget.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
function Get-Widget {
<#
.SYNOPSIS
Get a widget by name.
.DESCRIPTION
Returns a widget object with the requested name and quantity. This function exists only to
give the PowerShellBuild integration tests a public command with complete comment-based
help, typed parameters, and a private helper dependency.
.PARAMETER Name
Name of the widget to return.
.PARAMETER Quantity
Number of widget units to report on the returned object. Defaults to 1.
.EXAMPLE
PS> Get-Widget -Name 'Sprocket'

Returns a widget object named Sprocket with a quantity of 1.
.EXAMPLE
PS> Get-Widget -Name 'Sprocket' -Quantity 5

Returns a widget object named Sprocket with a quantity of 5.
.OUTPUTS
System.Management.Automation.PSCustomObject
#>
[CmdletBinding()]
[OutputType([PSCustomObject])]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$Name,

[Parameter()]
[ValidateRange(1, 1000)]
[int]
$Quantity = 1
)

if (-not (Test-WidgetName -Name $Name)) {
throw "Invalid widget name [$Name]"
}

[PSCustomObject]@{
Name = $Name
Quantity = $Quantity
}
}
44 changes: 44 additions & 0 deletions tests/fixtures/PSBuildTestFixture/Public/Set-Widget.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
function Set-Widget {
<#
.SYNOPSIS
Set the quantity of a widget.
.DESCRIPTION
Returns a widget object with the supplied name and quantity, as if the widget had been
updated. This function exists only to give the PowerShellBuild integration tests a second
public command, including one that supports ShouldProcess.
.PARAMETER Name
Name of the widget to update.
.PARAMETER Quantity
New number of widget units.
.EXAMPLE
PS> Set-Widget -Name 'Sprocket' -Quantity 3

Sets the Sprocket widget quantity to 3 and returns the updated widget object.
.OUTPUTS
System.Management.Automation.PSCustomObject
#>
[CmdletBinding(SupportsShouldProcess)]
[OutputType([PSCustomObject])]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$Name,

[Parameter(Mandatory)]
[ValidateRange(1, 1000)]
[int]
$Quantity
)

if (-not (Test-WidgetName -Name $Name)) {
throw "Invalid widget name [$Name]"
}

if ($PSCmdlet.ShouldProcess($Name, 'Set widget quantity')) {
[PSCustomObject]@{
Name = $Name
Quantity = $Quantity
}
}
}
3 changes: 3 additions & 0 deletions tests/fixtures/PSBuildTestFixture/excludeme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
=== EXCLUDE ME ===
This file exists so integration tests can assert that $PSBPreference.Build.Exclude
patterns keep matching files out of the build output.
Loading