@@ -76,11 +76,11 @@ Add-Type -TypeDefinition @"
7676 }
7777
7878 It " Should flag New-Object with disallowed TypeName" {
79- $def = ' New-Object -TypeName System.Net.WebClient '
79+ $def = ' New-Object -TypeName System.IO.File '
8080 $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
8181 $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
8282 $matchingViolations.Count | Should - Be 1
83- $matchingViolations [0 ].Message | Should - BeLike " *System.Net.WebClient *not permitted*"
83+ $matchingViolations [0 ].Message | Should - BeLike " *System.IO.File *not permitted*"
8484 }
8585 }
8686
@@ -172,11 +172,11 @@ enum MyEnum {
172172
173173 Context " When type expressions are used" {
174174 It " Should flag static type reference with new()" {
175- $def = ' $instance = [System.Net.WebClient ]::new()'
175+ $def = ' $instance = [System.IO.Directory ]::new()'
176176 $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
177177 $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
178178 $matchingViolations.Count | Should - BeGreaterThan 0
179- $matchingViolations [0 ].Message | Should - BeLike " *System.Net.WebClient *"
179+ $matchingViolations [0 ].Message | Should - BeLike " *System.IO.Directory *"
180180 }
181181
182182 It " Should flag static method call on disallowed type" {
@@ -388,9 +388,9 @@ enum MyEnum {
388388 It " Should flag multiple type issues in same script" {
389389 $def = @'
390390function Test {
391- param([System.Net.WebClient]$Client )
392- [System.Net.Sockets.TcpClient]$tcp = $null
393- $web = [System.Net.WebClient ]::new()
391+ param([System.IO.File]$FileHelper )
392+ [System.IO.Directory]$dirHelper = $null
393+ $pathHelper = [System.IO.Path ]::new()
394394}
395395'@
396396 $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
@@ -401,41 +401,89 @@ function Test {
401401 }
402402 }
403403
404+ Context " When PSCustomObject type cast is used" {
405+ It " Should flag [PSCustomObject]@{} syntax" {
406+ $def = ' $obj = [PSCustomObject]@{ Name = "Test"; Value = 42 }'
407+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
408+ $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
409+ $matchingViolations.Count | Should - BeGreaterThan 0
410+ $matchingViolations [0 ].Message | Should - BeLike " *PSCustomObject*"
411+ }
412+
413+ It " Should flag multiple [PSCustomObject]@{} instances" {
414+ $def = @'
415+ $obj1 = [PSCustomObject]@{ Name = "Test1" }
416+ $obj2 = [PSCustomObject]@{ Name = "Test2" }
417+ '@
418+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
419+ $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
420+ $matchingViolations.Count | Should - Be 2
421+ }
422+
423+ It " Should NOT flag PSCustomObject as parameter type" {
424+ $def = ' function Test { param([PSCustomObject]$InputObject) }'
425+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
426+ $violations | Where-Object { $_.RuleName -eq $violationName } | Should - BeNullOrEmpty
427+ }
428+
429+ It " Should NOT flag New-Object PSObject" {
430+ $def = ' $obj = New-Object PSObject -Property @{ Name = "Test" }'
431+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
432+ $violations | Where-Object { $_.RuleName -eq $violationName } | Should - BeNullOrEmpty
433+ }
434+
435+ It " Should NOT flag plain hashtables" {
436+ $def = ' $obj = @{ Name = "Test"; Value = 42 }'
437+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
438+ $violations | Where-Object { $_.RuleName -eq $violationName } | Should - BeNullOrEmpty
439+ }
440+
441+ It " Should NOT flag [PSCustomObject] with variable (not hashtable literal)" {
442+ $def = ' $hash = @{}; $obj = [PSCustomObject]$hash'
443+ $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
444+ $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
445+ # This is a type cast but not the @{} literal pattern
446+ # Since PSCustomObject is in allowed list, this won't be flagged
447+ $matchingViolations | Should - BeNullOrEmpty
448+ }
449+
450+ }
451+
404452 Context " When instance methods are invoked on disallowed types" {
405453 It " Should flag method invocation on parameter with disallowed type constraint" {
406454 $def = @'
407- function Download -File {
408- param([System.Net.WebClient]$Client , [string]$Url )
409- $Client.DownloadString($Url )
455+ function Read -File {
456+ param([System.IO.File]$FileHelper , [string]$Path )
457+ $FileHelper.ReadAllText($Path )
410458}
411459'@
412460 $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
413461 $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
414462 # Should flag both the type constraint AND the member access
415463 $matchingViolations.Count | Should - BeGreaterThan 1
416- # At least one violation should mention DownloadString
417- ($matchingViolations.Message | Where-Object { $_ -like " *DownloadString *" }).Count | Should - BeGreaterThan 0
464+ # At least one violation should mention ReadAllText
465+ ($matchingViolations.Message | Where-Object { $_ -like " *ReadAllText *" }).Count | Should - BeGreaterThan 0
418466 }
419467
420468 It " Should flag property access on variable with disallowed type constraint" {
421469 $def = @'
422470function Test {
423- param([System.Net.WebClient]$Client )
424- $baseAddr = $Client.BaseAddress
471+ param([System.IO.FileInfo]$FileHelper )
472+ $fullPath = $FileHelper.FullName
425473}
426474'@
427475 $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
428476 $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
429477 # Should flag both the type constraint AND the member access
430478 $matchingViolations.Count | Should - BeGreaterThan 1
431- # At least one violation should mention BaseAddress
432- ($matchingViolations.Message | Where-Object { $_ -like " *BaseAddress *" }).Count | Should - BeGreaterThan 0
479+ # At least one violation should mention FullName
480+ ($matchingViolations.Message | Where-Object { $_ -like " *FullName *" }).Count | Should - BeGreaterThan 0
433481 }
434482
435483 It " Should flag method invocation on typed variable assignment" {
436484 $def = @'
437- [System.Net.WebClient]$client = $null
438- $result = $client.DownloadString("http://example.com ")
485+ [System.IO.File]$fileHelper = $null
486+ $result = $fileHelper.ReadAllText("C:\test.txt ")
439487'@
440488 $violations = Invoke-ScriptAnalyzer - ScriptDefinition $def - Settings $settings
441489 $matchingViolations = $violations | Where-Object { $_.RuleName -eq $violationName }
0 commit comments