Skip to content

Commit f53f0d6

Browse files
🩹 [Patch]: Add tests and update linter (#37)
## Description - Add test data - Update linter ## Type of change <!-- Use the check-boxes [x] on the options that are relevant. --> - [ ] 📖 [Docs] - [ ] 🪲 [Fix] - [x] 🩹 [Patch] - [x] ⚠️ [Security fix] - [ ] 🚀 [Feature] - [ ] 🌟 [Breaking change] ## Checklist <!-- Use the check-boxes [x] on the options that are relevant. --> - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas
1 parent 7effee7 commit f53f0d6

24 files changed

+522
-14
lines changed

.github/workflows/Action-Test.yml

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ on: [pull_request]
77
env:
88
GH_TOKEN: ${{ github.token }}
99

10+
permissions: {}
11+
1012
jobs:
1113
ActionTestDefault:
1214
name: Action-Test - [Default]
@@ -15,24 +17,13 @@ jobs:
1517
- name: Checkout repo
1618
uses: actions/checkout@v4
1719

18-
- name: Checkout tests -> PSModuleTest
19-
uses: actions/checkout@v4
20-
with:
21-
repository: PSModule/PSModuleTest
22-
path: tests
23-
24-
- name: Delete outputs
25-
shell: pwsh
26-
run: |
27-
Remove-Item -Path tests/outputs -Recurse -Force -Verbose
28-
2920
- name: Initialize environment
3021
uses: PSModule/Initialize-PSModule@main
3122

3223
- name: Action-Test
3324
uses: ./
3425
with:
35-
Name: PSModule
26+
Name: PSModuleTest
3627
Path: tests/src
3728
ModulesOutputPath: tests/outputs/modules
3829
DocsOutputPath: tests/outputs/docs

.github/workflows/Linter.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@ run-name: "Linter - [${{ github.event.pull_request.title }} #${{ github.event.pu
44

55
on: [pull_request]
66

7+
permissions:
8+
contents: read
9+
packages: read
10+
statuses: write # To report GitHub Actions status checks
11+
712
jobs:
813
Lint:
914
name: Lint code base
1015
runs-on: ubuntu-latest
1116
steps:
1217
- name: Checkout repo
1318
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
1421

1522
- name: Lint code base
16-
uses: github/super-linter@latest
23+
uses: super-linter/super-linter@latest
1724
env:
1825
GITHUB_TOKEN: ${{ github.token }}

scripts/helpers/Build/Build-PSModuleManifest.ps1

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,11 @@ function Build-PSModuleManifest {
333333
Show-FileContent -Path $outputManifestPath
334334
Stop-LogGroup
335335

336-
Start-LogGroup 'Build manifest file - Result - After format'
336+
Start-LogGroup 'Build manifest file - Format'
337337
Set-ModuleManifest -Path $outputManifestPath
338+
Stop-LogGroup
339+
340+
Start-LogGroup 'Build manifest file - Result - After format'
338341
Show-FileContent -Path $outputManifestPath
339342
Stop-LogGroup
340343

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@{
2+
ModuleVersion = '0.0.0'
3+
RootModule = 'PSModuleTest.psm1'
4+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
[Cmdletbinding()]
2+
param()
3+
4+
Write-Verbose 'Importing subcomponents'
5+
$Folders = 'init', 'classes', 'private', 'public'
6+
# Import everything in these folders
7+
Foreach ($Folder in $Folders) {
8+
$Root = Join-Path -Path $PSScriptRoot -ChildPath $Folder
9+
Write-Verbose "Processing folder: $Root"
10+
if (Test-Path -Path $Root) {
11+
Write-Verbose "Getting all files in $Root"
12+
$Files = $null
13+
$Files = Get-ChildItem -Path $Root -Include '*.ps1', '*.psm1' -Recurse
14+
# dot source each file
15+
foreach ($File in $Files) {
16+
Write-Verbose "Importing $($File)"
17+
Import-Module $File
18+
Write-Verbose "Importing $($File): Done"
19+
}
20+
}
21+
}
22+
23+
. "$PSScriptRoot\finally.ps1"
24+
25+
# Define the types to export with type accelerators.
26+
$ExportableTypes = @(
27+
[Book]
28+
[BookList]
29+
)
30+
31+
# Get the internal TypeAccelerators class to use its static methods.
32+
$TypeAcceleratorsClass = [psobject].Assembly.GetType(
33+
'System.Management.Automation.TypeAccelerators'
34+
)
35+
# Ensure none of the types would clobber an existing type accelerator.
36+
# If a type accelerator with the same name exists, throw an exception.
37+
$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get
38+
foreach ($Type in $ExportableTypes) {
39+
if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
40+
$Message = @(
41+
"Unable to register type accelerator '$($Type.FullName)'"
42+
'Accelerator already exists.'
43+
) -join ' - '
44+
45+
throw [System.Management.Automation.ErrorRecord]::new(
46+
[System.InvalidOperationException]::new($Message),
47+
'TypeAcceleratorAlreadyExists',
48+
[System.Management.Automation.ErrorCategory]::InvalidOperation,
49+
$Type.FullName
50+
)
51+
}
52+
}
53+
# Add type accelerators for every exportable type.
54+
foreach ($Type in $ExportableTypes) {
55+
$TypeAcceleratorsClass::Add($Type.FullName, $Type)
56+
}
57+
# Remove type accelerators when the module is removed.
58+
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
59+
foreach ($Type in $ExportableTypes) {
60+
$TypeAcceleratorsClass::Remove($Type.FullName)
61+
}
62+
}.GetNewClosure()
63+
64+
$Param = @{
65+
Function = (Get-ChildItem -Path "$PSScriptRoot\public" -Include '*.ps1' -Recurse).BaseName
66+
Variable = '*'
67+
Cmdlet = '*'
68+
Alias = '*'
69+
}
70+
71+
Write-Verbose 'Exporting module members'
72+
73+
Export-ModuleMember @Param
42.5 KB
Binary file not shown.
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
class Book {
2+
# Class properties
3+
[string] $Title
4+
[string] $Author
5+
[string] $Synopsis
6+
[string] $Publisher
7+
[datetime] $PublishDate
8+
[int] $PageCount
9+
[string[]] $Tags
10+
# Default constructor
11+
Book() { $this.Init(@{}) }
12+
# Convenience constructor from hashtable
13+
Book([hashtable]$Properties) { $this.Init($Properties) }
14+
# Common constructor for title and author
15+
Book([string]$Title, [string]$Author) {
16+
$this.Init(@{Title = $Title; Author = $Author })
17+
}
18+
# Shared initializer method
19+
[void] Init([hashtable]$Properties) {
20+
foreach ($Property in $Properties.Keys) {
21+
$this.$Property = $Properties.$Property
22+
}
23+
}
24+
# Method to calculate reading time as 2 minutes per page
25+
[timespan] GetReadingTime() {
26+
if ($this.PageCount -le 0) {
27+
throw 'Unable to determine reading time from page count.'
28+
}
29+
$Minutes = $this.PageCount * 2
30+
return [timespan]::new(0, $Minutes, 0)
31+
}
32+
# Method to calculate how long ago a book was published
33+
[timespan] GetPublishedAge() {
34+
if (
35+
$null -eq $this.PublishDate -or
36+
$this.PublishDate -eq [datetime]::MinValue
37+
) { throw 'PublishDate not defined' }
38+
39+
return (Get-Date) - $this.PublishDate
40+
}
41+
# Method to return a string representation of the book
42+
[string] ToString() {
43+
return "$($this.Title) by $($this.Author) ($($this.PublishDate.Year))"
44+
}
45+
}
46+
47+
class BookList {
48+
# Static property to hold the list of books
49+
static [System.Collections.Generic.List[Book]] $Books
50+
# Static method to initialize the list of books. Called in the other
51+
# static methods to avoid needing to explicit initialize the value.
52+
static [void] Initialize() { [BookList]::Initialize($false) }
53+
static [bool] Initialize([bool]$force) {
54+
if ([BookList]::Books.Count -gt 0 -and -not $force) {
55+
return $false
56+
}
57+
58+
[BookList]::Books = [System.Collections.Generic.List[Book]]::new()
59+
60+
return $true
61+
}
62+
# Ensure a book is valid for the list.
63+
static [void] Validate([book]$Book) {
64+
$Prefix = @(
65+
'Book validation failed: Book must be defined with the Title,'
66+
'Author, and PublishDate properties, but'
67+
) -join ' '
68+
if ($null -eq $Book) { throw "$Prefix was null" }
69+
if ([string]::IsNullOrEmpty($Book.Title)) {
70+
throw "$Prefix Title wasn't defined"
71+
}
72+
if ([string]::IsNullOrEmpty($Book.Author)) {
73+
throw "$Prefix Author wasn't defined"
74+
}
75+
if ([datetime]::MinValue -eq $Book.PublishDate) {
76+
throw "$Prefix PublishDate wasn't defined"
77+
}
78+
}
79+
# Static methods to manage the list of books.
80+
# Add a book if it's not already in the list.
81+
static [void] Add([Book]$Book) {
82+
[BookList]::Initialize()
83+
[BookList]::Validate($Book)
84+
if ([BookList]::Books.Contains($Book)) {
85+
throw "Book '$Book' already in list"
86+
}
87+
88+
$FindPredicate = {
89+
param([Book]$b)
90+
91+
$b.Title -eq $Book.Title -and
92+
$b.Author -eq $Book.Author -and
93+
$b.PublishDate -eq $Book.PublishDate
94+
}.GetNewClosure()
95+
if ([BookList]::Books.Find($FindPredicate)) {
96+
throw "Book '$Book' already in list"
97+
}
98+
99+
[BookList]::Books.Add($Book)
100+
}
101+
# Clear the list of books.
102+
static [void] Clear() {
103+
[BookList]::Initialize()
104+
[BookList]::Books.Clear()
105+
}
106+
# Find a specific book using a filtering scriptblock.
107+
static [Book] Find([scriptblock]$Predicate) {
108+
[BookList]::Initialize()
109+
return [BookList]::Books.Find($Predicate)
110+
}
111+
# Find every book matching the filtering scriptblock.
112+
static [Book[]] FindAll([scriptblock]$Predicate) {
113+
[BookList]::Initialize()
114+
return [BookList]::Books.FindAll($Predicate)
115+
}
116+
# Remove a specific book.
117+
static [void] Remove([Book]$Book) {
118+
[BookList]::Initialize()
119+
[BookList]::Books.Remove($Book)
120+
}
121+
# Remove a book by property value.
122+
static [void] RemoveBy([string]$Property, [string]$Value) {
123+
[BookList]::Initialize()
124+
$Index = [BookList]::Books.FindIndex({
125+
param($b)
126+
$b.$Property -eq $Value
127+
}.GetNewClosure())
128+
if ($Index -ge 0) {
129+
[BookList]::Books.RemoveAt($Index)
130+
}
131+
}
132+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@{
2+
RandomKey = 'RandomValue'
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@{
2+
RandomSetting = 'RandomSettingValue'
3+
}

tests/src/PSModuleTest/finally.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Write-Verbose '------------------------------' -Verbose
2+
Write-Verbose '--- THIS IS A LAST LOADER ---' -Verbose
3+
Write-Verbose '------------------------------' -Verbose

0 commit comments

Comments
 (0)