Files
PowerShell-PowerShell/test/powershell/Language/LanguageTestSupport.psm1
T

179 lines
5.2 KiB
PowerShell

#
# Run the new parser, return either errors or the ast
#
function Get-ParseResults
{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[string]$src,
[switch]$Ast
)
$errors = $null
$result = [System.Management.Automation.Language.Parser]::ParseInput($src, [ref]$null, [ref]$errors)
if ($Ast) { $result } else { ,$errors }
}
#
# Run script and return errors
#
function Get-RuntimeError
{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[string]$src
)
$errors = $null
try
{
[scriptblock]::Create($src).Invoke() > $null
}
catch
{
return $_.Exception.InnerException.ErrorRecord
}
}
function position_message
{
param($position)
if ($position.Line.Length -lt $position.ColumnNumber)
{
$position.Line + " <<<<"
}
else
{
$position.Line.Insert($position.ColumnNumber, " <<<<")
}
}
#
# Run the new parser, check the errors against the expected errors
#
function Test-Error
{
[CmdletBinding()]
param([string]$src, [string[]]$expectedErrors, [int[]]$expectedOffsets)
Assert ($expectedErrors.Count -eq $expectedOffsets.Count) "Test case error"
$errors = Get-ParseResults -Src $src
if ($null -ne $errors)
{
Assert ($errors.Count -eq $expectedErrors.Count) "Expected $($expectedErrors.Count) errors, got $($errors.Count)"
for ($i = 0; $i -lt $errors.Count; ++$i)
{
$err = $errors[$i]
Assert ($expectedErrors[$i] -eq $err.ErrorId) ("Unexpected error: {0,-30}{1}" -f ("$($err.ErrorId):",
(position_message $err.Extent.StartScriptPosition)))
Assert ($expectedOffsets[$i] -eq $err.Extent.StartScriptPosition.Offset) `
"Expected position: $($expectedOffsets[$i]), got $($err.Extent.StartScriptPosition.Offset)"
}
}
else
{
Assert $false "Expected errors but didn't receive any."
}
}
#
# Pester friendly version of Test-Error
#
function ShouldBeParseError
{
[CmdletBinding()]
param(
[string]$src,
[string[]]$expectedErrors,
[int[]]$expectedOffsets,
# This is a temporary solution after moving type creation from parse time to runtime
[switch]$SkipAndCheckRuntimeError
)
Context "Parse error expected: <<$src>>" {
# Test case error if this fails
$expectedErrors.Count | Should Be $expectedOffsets.Count
if ($SkipAndCheckRuntimeError)
{
It "error should happen at parse time, not at runtime" -Skip {}
$errors = Get-RuntimeError -Src $src
# for runtime errors we will only get the first one
$expectedErrors = ,$expectedErrors[0]
$expectedOffsets = ,$expectedOffsets[0]
}
else
{
$errors = Get-ParseResults -Src $src
}
It "Error count" { $errors.Count | Should Be $expectedErrors.Count }
for ($i = 0; $i -lt $errors.Count; ++$i)
{
$err = $errors[$i]
if ($SkipAndCheckRuntimeError)
{
$errorId = $err.FullyQualifiedErrorId
}
else
{
$errorId = $err.ErrorId
}
It "Error Id" { $errorId | Should Be $expectedErrors[$i] }
It "Error position" -Pending:$SkipAndCheckRuntimeError { $err.Extent.StartScriptPosition.Offset | Should Be $expectedOffsets[$i] }
}
}
}
function Flatten-Ast
{
[CmdletBinding()]
param([System.Management.Automation.Language.Ast] $ast)
$ast
$ast | gm -type property | ? { ($prop = $_.Name) -ne 'Parent' } | % {
$ast.$prop | ? { $_ -is [System.Management.Automation.Language.Ast] } | % { Flatten-Ast $_ }
}
}
function Test-ErrorStmt
{
param([string]$src, [string]$errorStmtExtent)
$ast = Get-ParseResults $src -Ast
$asts = @(Flatten-Ast $ast.EndBlock.Statements[0])
Assert ($asts[0] -is [System.Management.Automation.Language.ErrorStatementAst]) "Expected error statement"
Assert ($asts.Count -eq $args.Count + 1) "Incorrect number of nested asts"
Assert ($asts[0].Extent.Text -eq $errorStmtExtent) "Error statement expected <$errorStmtExtent>, got <$($asts[0].Extent.Text)>"
for ($i = 0; $i -lt $args.Count; ++$i)
{
Assert ($asts[$i + 1].Extent.Text -eq $args[$i]) "Nested ast incorrect: <$($asts[$i+1].Extent.Text)>, expected <$($args[$i])>"
}
}
function Test-Ast
{
param([string]$src)
$ast = Get-ParseResults $src -Ast
$asts = @(Flatten-Ast $ast)
Assert ($asts.Count -eq $args.Count) "Incorrect number of nested asts, got $($asts.Count), expected $($args.Count)"
for ($i = 0; $i -lt $args.Count; ++$i)
{
Assert ($asts[$i].Extent.Text -eq $args[$i]) "Nested ast incorrect: <$($asts[$i].Extent.Text)>, expected <$($args[$i])>"
}
}
Export-ModuleMember -Function Test-Error, Test-ErrorStmt, Test-Ast, ShouldBeParseError, Get-ParseResults, Get-RuntimeError