tests/ModuleState.Tests.ps1
|
#Requires -Version 7.0 # Module files share one script scope when DotForge is imported, so two files # initializing the same $script: variable at load time silently clobber each # other (tests that dot-source files one at a time never see it). Describe 'Module script-scope state' { It 'no two module files initialize the same $script: variable at load time' { $root = Split-Path $PSScriptRoot -Parent $owners = @{} foreach ($file in Get-ChildItem (Join-Path $root 'Shared'), (Join-Path $root 'Private'), (Join-Path $root 'Public'), (Join-Path $root 'Modules' 'DotForge.Catalog' 'Private'), (Join-Path $root 'Modules' 'DotForge.Catalog' 'Public'), (Join-Path $root 'Modules' 'DotForge.Helpers' 'Private'), (Join-Path $root 'Modules' 'DotForge.Helpers' 'Public') -Filter '*.ps1') { $ast = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$null, [ref]$null) # Top-level statements only (not inside functions). foreach ($stmt in $ast.EndBlock.Statements) { $assigns = $stmt.FindAll({ param($n) $n -is [System.Management.Automation.Language.AssignmentStatementAst] -and $n.Left -is [System.Management.Automation.Language.VariableExpressionAst] -and $n.Left.VariablePath.UserPath -like 'script:*' }, $true) foreach ($a in $assigns) { $name = $a.Left.VariablePath.UserPath -replace '^script:' if (-not $owners[$name]) { $owners[$name] = [System.Collections.Generic.HashSet[string]]::new() } $null = $owners[$name].Add($file.Name) } } } $shared = @($owners.GetEnumerator() | Where-Object { $_.Value.Count -gt 1 } | ForEach-Object { "$($_.Key): $($_.Value -join ', ')" }) $shared | Should -BeNullOrEmpty } } |