<commit_before>﻿$sa = Get-Command Invoke-ScriptAnalyzer
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
$singularNouns = "PSUseSingularNouns"
$approvedVerb = "PSUseApprovedVerbs"
$rules = Get-ScriptAnalyzerRule -Name ($singularNouns, "PSUseApprovedVerbs")
$avoidRules = Get-ScriptAnalyzerRule -Name "PSAvoid*"
$useRules = "PSUse*"

Describe "Test available parameters" {
    $params = $sa.Parameters
    Context "Path parameter" {
        It "has a Path parameter" {
            $params.ContainsKey("Path") | Should -BeTrue
        }

        It "accepts string" {
            $params["Path"].ParameterType.FullName | Should -Be "System.String"
        }
    }

    Context "Path parameter" {
        It "has a ScriptDefinition parameter" {
            $params.ContainsKey("ScriptDefinition") | Should -BeTrue
        }

        It "accepts string" {
            $params["ScriptDefinition"].ParameterType.FullName | Should -Be "System.String"
        }
    }

    Context "CustomRulePath parameters" {
        It "has a CustomRulePath parameter" {
            $params.ContainsKey("CustomRulePath") | Should -BeTrue
        }

        It "accepts a string array" {
				$params["CustomRulePath"].ParameterType.FullName | Should -Be "System.String[]"
        }

		It "has a CustomizedRulePath alias"{
			$params.CustomRulePath.Aliases.Contains("CustomizedRulePath") | Should -BeTrue
		}
    }

    Context "IncludeRule parameters" {
        It "has an IncludeRule parameter" {
            $params.ContainsKey("IncludeRule") | Should -BeTrue
        }

        It "accepts string array" {
            $params["IncludeRule"].ParameterType.FullName | Should -Be "System.String[]"
        }
    }

    Context "Severity parameters" {
        It "has a severity parameters" {
            $params.ContainsKey("Severity") | Should -BeTrue
        }

        It "accepts string array" {
            $params["Severity"].ParameterType.FullName | Should -Be "System.String[]"
        }
    }

    if (!$testingLibraryUsage -and ($PSVersionTable.PSVersion -ge [Version]'5.0.0'))
    {
        Context "SaveDscDependency parameter" {
            It "has the parameter" {
                $params.ContainsKey("SaveDscDependency") | Should -BeTrue
            }

            It "is a switch parameter" {
                $params["SaveDscDependency"].ParameterType.FullName | Should -Be "System.Management.Automation.SwitchParameter"
            }
        }
    }

    Context "It has 2 parameter sets: File and ScriptDefinition" {
        It "Has 2 parameter sets" {
            $sa.ParameterSets.Count | Should -Be 2
        }

        It "Has File parameter set" {
            $hasFile = $false
            foreach ($paramSet in $sa.ParameterSets) {
                if ($paramSet.Name -eq "File") {
                    $hasFile = $true
                    break
                }
            }

            $hasFile | Should -BeTrue
        }

        It "Has ScriptDefinition parameter set" {
            $hasFile = $false
            foreach ($paramSet in $sa.ParameterSets) {
                if ($paramSet.Name -eq "ScriptDefinition") {
                    $hasFile = $true
                    break
                }
            }

            $hasFile | Should -BeTrue
        }

    }
}

Describe "Test ScriptDefinition" {
    Context "When given a script definition" {
        It "Does not run rules on script with more than 10 parser errors" {
            $moreThanTenErrors = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue -ScriptDefinition (Get-Content -Raw "$directory\CSharp.ps1")
            $moreThanTenErrors.Count | Should -Be 0
        }
    }
}

Describe "Test Path" {
    Context "When given a single file" {
        It "Has the same effect as without Path parameter" {
            $withPath = Invoke-ScriptAnalyzer $directory\TestScript.ps1
            $withoutPath = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1
            $withPath.Count -eq $withoutPath.Count | Should -BeTrue
        }

        It "Does not run rules on script with more than 10 parser errors" {
            $moreThanTenErrors = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\CSharp.ps1
            $moreThanTenErrors.Count | Should -Be 0
        }
    }

    Context "DiagnosticRecord  " {
	It "has valid ScriptPath and ScriptName properties when an input file is given" {
	   $scriptName = "TestScript.ps1"
	   $scriptPath = Join-Path $directory $scriptName
	   $expectedScriptPath = Resolve-Path $directory\TestScript.ps1
	   $diagnosticRecords = Invoke-ScriptAnalyzer $scriptPath -IncludeRule "PSAvoidUsingEmptyCatchBlock"
	   $diagnosticRecords[0].ScriptPath | Should -Be $expectedScriptPath.Path
	   $diagnosticRecords[0].ScriptName | Should -Be $scriptName
	}

	It "has empty ScriptPath and ScriptName properties when a script definition is given" {
	   $diagnosticRecords = Invoke-ScriptAnalyzer -ScriptDefinition gci -IncludeRule "PSAvoidUsingCmdletAliases"
	   $diagnosticRecords[0].ScriptPath | Should -Be ([System.String]::Empty)
	   $diagnosticRecords[0].ScriptName | Should -Be ([System.String]::Empty)
	}
    }

	if (!$testingLibraryUsage)
	{
		#There is probably a more concise way to do this but for now we will settle for this!
		Function GetFreeDrive ($freeDriveLen) {
			$ordA = 65
			$ordZ = 90
			$freeDrive = ""
			$freeDriveName = ""
			do{
				$freeDriveName = (1..$freeDriveLen | %{[char](Get-Random -Maximum $ordZ -Minimum $ordA)}) -join ''
				$freeDrive = $freeDriveName + ":"
			}while(Test-Path $freeDrive)
			$freeDrive, $freeDriveName
		}

		Context "When given a glob" {
    		It "Invokes on all the matching files" {
			$numFilesResult = (Invoke-ScriptAnalyzer -Path $directory\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count
			$numFilesExpected = (Get-ChildItem -Path $directory\TestTestPath*.ps1).Count
			$numFilesResult | Should -Be $numFilesExpected
			}
		}

		Context "When given a FileSystem PSDrive" {
    		It "Recognizes the path" {
			$freeDriveNameLen = 2
			$freeDrive, $freeDriveName = GetFreeDrive $freeDriveNameLen
			New-PSDrive -Name $freeDriveName -PSProvider FileSystem -Root $directory
			$numFilesExpected = (Get-ChildItem -Path $freeDrive\TestTestPath*.ps1).Count
			$numFilesResult = (Invoke-ScriptAnalyzer -Path $freeDrive\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count
			Remove-PSDrive $freeDriveName
			$numFilesResult | Should -Be $numFilesExpected
			}
		}
	}

    Context "When given a directory" {
        $withoutPathWithDirectory = Invoke-ScriptAnalyzer -Recurse $directory\RecursionDirectoryTest
        $withPathWithDirectory = Invoke-ScriptAnalyzer -Recurse -Path $directory\RecursionDirectoryTest

        It "Has the same count as without Path parameter"{
            $withoutPathWithDirectory.Count -eq $withPathWithDirectory.Count | Should -BeTrue
        }

        It "Analyzes all the files" {
            $globalVarsViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidGlobalVars"}
            $clearHostViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidUsingClearHost"}
            $writeHostViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidUsingWriteHost"}
            Write-Output $globalVarsViolation.Count
            Write-Output $clearHostViolation.Count
            Write-Output $writeHostViolation.Count
            $globalVarsViolation.Count -eq 1 -and $writeHostViolation.Count -eq 1 | Should -BeTrue
        }
    }
}

Describe "Test ExcludeRule" {
    Context "When used correctly" {
        It "excludes 1 rule" {
            $noViolations = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -ExcludeRule $singularNouns | Where-Object {$_.RuleName -eq $singularNouns}<commit_msg>add test cases for piping<commit_after>﻿$sa = Get-Command Invoke-ScriptAnalyzer
$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
$singularNouns = "PSUseSingularNouns"
$approvedVerb = "PSUseApprovedVerbs"
$rules = Get-ScriptAnalyzerRule -Name ($singularNouns, "PSUseApprovedVerbs")
$avoidRules = Get-ScriptAnalyzerRule -Name "PSAvoid*"
$useRules = "PSUse*"

Describe "Test available parameters" {
    $params = $sa.Parameters
    Context "Path parameter" {
        It "has a Path parameter" {
            $params.ContainsKey("Path") | Should -BeTrue
        }

        It "accepts string" {
            $params["Path"].ParameterType.FullName | Should -Be "System.String"
        }
    }

    Context "Path parameter" {
        It "has a ScriptDefinition parameter" {
            $params.ContainsKey("ScriptDefinition") | Should -BeTrue
        }

        It "accepts string" {
            $params["ScriptDefinition"].ParameterType.FullName | Should -Be "System.String"
        }
    }

    Context "CustomRulePath parameters" {
        It "has a CustomRulePath parameter" {
            $params.ContainsKey("CustomRulePath") | Should -BeTrue
        }

        It "accepts a string array" {
				$params["CustomRulePath"].ParameterType.FullName | Should -Be "System.String[]"
        }

		It "has a CustomizedRulePath alias"{
			$params.CustomRulePath.Aliases.Contains("CustomizedRulePath") | Should -BeTrue
		}
    }

    Context "IncludeRule parameters" {
        It "has an IncludeRule parameter" {
            $params.ContainsKey("IncludeRule") | Should -BeTrue
        }

        It "accepts string array" {
            $params["IncludeRule"].ParameterType.FullName | Should -Be "System.String[]"
        }
    }

    Context "Severity parameters" {
        It "has a severity parameters" {
            $params.ContainsKey("Severity") | Should -BeTrue
        }

        It "accepts string array" {
            $params["Severity"].ParameterType.FullName | Should -Be "System.String[]"
        }
    }

    if (!$testingLibraryUsage -and ($PSVersionTable.PSVersion -ge [Version]'5.0.0'))
    {
        Context "SaveDscDependency parameter" {
            It "has the parameter" {
                $params.ContainsKey("SaveDscDependency") | Should -BeTrue
            }

            It "is a switch parameter" {
                $params["SaveDscDependency"].ParameterType.FullName | Should -Be "System.Management.Automation.SwitchParameter"
            }
        }
    }

    Context "It has 2 parameter sets: File and ScriptDefinition" {
        It "Has 2 parameter sets" {
            $sa.ParameterSets.Count | Should -Be 2
        }

        It "Has File parameter set" {
            $hasFile = $false
            foreach ($paramSet in $sa.ParameterSets) {
                if ($paramSet.Name -eq "File") {
                    $hasFile = $true
                    break
                }
            }

            $hasFile | Should -BeTrue
        }

        It "Has ScriptDefinition parameter set" {
            $hasFile = $false
            foreach ($paramSet in $sa.ParameterSets) {
                if ($paramSet.Name -eq "ScriptDefinition") {
                    $hasFile = $true
                    break
                }
            }

            $hasFile | Should -BeTrue
        }

    }
}

Describe "Test ScriptDefinition" {
    Context "When given a script definition" {
        It "Does not run rules on script with more than 10 parser errors" {
            $moreThanTenErrors = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue -ScriptDefinition (Get-Content -Raw "$directory\CSharp.ps1")
            $moreThanTenErrors.Count | Should -Be 0
        }
    }
}

Describe "Test Path" {
    Context "When given a single file" {
        It "Has the same effect as without Path parameter" {
            $withPath = Invoke-ScriptAnalyzer $directory\TestScript.ps1
            $withoutPath = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1
            $withPath.Count -eq $withoutPath.Count | Should -BeTrue
        }

        It "Does not run rules on script with more than 10 parser errors" {
            $moreThanTenErrors = Invoke-ScriptAnalyzer -ErrorAction SilentlyContinue $directory\CSharp.ps1
            $moreThanTenErrors.Count | Should -Be 0
        }
    }

    Context "DiagnosticRecord  " {
	It "has valid ScriptPath and ScriptName properties when an input file is given" {
	   $scriptName = "TestScript.ps1"
	   $scriptPath = Join-Path $directory $scriptName
	   $expectedScriptPath = Resolve-Path $directory\TestScript.ps1
	   $diagnosticRecords = Invoke-ScriptAnalyzer $scriptPath -IncludeRule "PSAvoidUsingEmptyCatchBlock"
	   $diagnosticRecords[0].ScriptPath | Should -Be $expectedScriptPath.Path
	   $diagnosticRecords[0].ScriptName | Should -Be $scriptName
	}

	It "has empty ScriptPath and ScriptName properties when a script definition is given" {
	   $diagnosticRecords = Invoke-ScriptAnalyzer -ScriptDefinition gci -IncludeRule "PSAvoidUsingCmdletAliases"
	   $diagnosticRecords[0].ScriptPath | Should -Be ([System.String]::Empty)
	   $diagnosticRecords[0].ScriptName | Should -Be ([System.String]::Empty)
	}
    }

	if (!$testingLibraryUsage)
	{
		#There is probably a more concise way to do this but for now we will settle for this!
		Function GetFreeDrive ($freeDriveLen) {
			$ordA = 65
			$ordZ = 90
			$freeDrive = ""
			$freeDriveName = ""
			do{
				$freeDriveName = (1..$freeDriveLen | %{[char](Get-Random -Maximum $ordZ -Minimum $ordA)}) -join ''
				$freeDrive = $freeDriveName + ":"
			}while(Test-Path $freeDrive)
			$freeDrive, $freeDriveName
		}

		Context "When given a glob" {
    		It "Invokes on all the matching files" {
			$numFilesResult = (Invoke-ScriptAnalyzer -Path $directory\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count
			$numFilesExpected = (Get-ChildItem -Path $directory\TestTestPath*.ps1).Count
			$numFilesResult | Should -Be $numFilesExpected
			}
		}

		Context "When given a FileSystem PSDrive" {
    		It "Recognizes the path" {
			$freeDriveNameLen = 2
			$freeDrive, $freeDriveName = GetFreeDrive $freeDriveNameLen
			New-PSDrive -Name $freeDriveName -PSProvider FileSystem -Root $directory
			$numFilesExpected = (Get-ChildItem -Path $freeDrive\TestTestPath*.ps1).Count
			$numFilesResult = (Invoke-ScriptAnalyzer -Path $freeDrive\TestTestPath*.ps1 | Select-Object -Property ScriptName -Unique).Count
			Remove-PSDrive $freeDriveName
			$numFilesResult | Should -Be $numFilesExpected
			}
        }
        
        Context "When piping in files" {
            It "Can be piped in from a string" {
                $piped = ("$directory\TestScript.ps1" | Invoke-ScriptAnalyzer)
                $explicit = Invoke-ScriptAnalyzer -Path $directory\TestScript.ps1
    
                $piped.Count -eq $explicit.Count | Should -BeTrue
            }
    
            It "Can be piped from Get-ChildItem" {
                $piped = ( Get-ChildItem -Path $directory -Filter TestTestPath*.ps1 | Invoke-ScriptAnalyzer)
                $explicit = Invoke-ScriptAnalyzer -Path $directory\TestTestPath*.ps1
                $piped.Count -eq $explicit.Count | Should -BeTrue
            }
        }
	}

    Context "When given a directory" {
        $withoutPathWithDirectory = Invoke-ScriptAnalyzer -Recurse $directory\RecursionDirectoryTest
        $withPathWithDirectory = Invoke-ScriptAnalyzer -Recurse -Path $directory\RecursionDirectoryTest

        It "Has the same count as without Path parameter"{
            $withoutPathWithDirectory.Count -eq $withPathWithDirectory.Count | Should -BeTrue
        }

        It "Analyzes all the files" {
            $globalVarsViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidGlobalVars"}
            $clearHostViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidUsingClearHost"}
            $writeHostViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidUsingWriteHost"}
            Write-Output $globalVarsViolation.Count
            Write-Output $clearHostViolation.Count
            Write-Output $writeHostViolation.Count
            $globalVarsViolation.Count -eq 1 -and $writeHostViolation.Count -eq 1 | Should -BeTrue
        }
    }
}

Describe "Test ExcludeRule" {
    Context "When used correctly" {
        It "excludes 1 rule" {
            $noViolations = Invoke-ScriptAnalyzer $directory\..\Rules\BadCmdlet.ps1 -ExcludeRule $singularNouns | Where-Object {$_.RuleName -eq $singularNouns}
{'fraction_non_alphanumeric': 0.10033670033670034, 'fraction_numerical': 0.004652586470768289, 'mean_word_length': 2.5305813702182838, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5440024', 'n_tokens_mistral': 4930, 'n_tokens_neox': 4607, 'n_words': 1178}