MegaBites-AI/Windows-powershell
0372
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3#4# Run the new parser, return either errors or the ast5#6 7function Get-ParseResults8{9 [CmdletBinding()]10 param(11 [Parameter(ValueFromPipeline=$true,Mandatory=$true)]12 [string]$src,13 [switch]$Ast14 )15 16 $errors = $null17 $result = [System.Management.Automation.Language.Parser]::ParseInput($src, [ref]$null, [ref]$errors)18 if ($Ast) { $result } else { ,$errors }19}20 21#22# Run script and return errors23#24function Get-RuntimeError25{26 [CmdletBinding()]27 param(28 [Parameter(ValueFromPipeline=$true,Mandatory=$true)][string]$src29 )30 31 $errors = $null32 try33 {34 [scriptblock]::Create($src).Invoke() > $null35 }36 catch37 {38 return $_.Exception.InnerException.ErrorRecord39 }40}41 42function position_message43{44 param($position)45 46 if ($position.Line.Length -lt $position.ColumnNumber)47 {48 $position.Line + " <<<<"49 }50 else51 {52 $position.Line.Insert($position.ColumnNumber, " <<<<")53 }54}55 56#57# Pester friendly version of Test-Error58#59function ShouldBeParseError60{61 [CmdletBinding()]62 param(63 [string]$src,64 [string[]]$expectedErrors,65 [int[]]$expectedOffsets,66 # This is a temporary solution after moving type creation from parse time to runtime67 [switch]$SkipAndCheckRuntimeError,68 # for test coverarage purpose, tests validate columnNumber or offset69 [switch]$CheckColumnNumber70 )71 72 Context "Parse error expected: <<$src>>" {73 # Test case error if this fails74 $expectedErrors.Count | Should -Be $expectedOffsets.Count75 76 if ($SkipAndCheckRuntimeError)77 {78 It "error should happen at parse time, not at runtime" -Skip {}79 $errors = Get-RuntimeError -Src $src80 # for runtime errors we will only get the first one81 $expectedErrors = ,$expectedErrors[0]82 $expectedOffsets = ,$expectedOffsets[0]83 }84 else85 {86 $errors = Get-ParseResults -Src $src87 }88 89 It "Error count" { $errors.Count | Should -Be $expectedErrors.Count }90 for ($i = 0; $i -lt $errors.Count; ++$i)91 {92 $err = $errors[$i]93 94 if ($SkipAndCheckRuntimeError)95 {96 $errorId = $err.FullyQualifiedErrorId97 }98 else99 {100 $errorId = $err.ErrorId101 }102 It "Error Id (iteration:$i)" { $errorId | Should -Be $expectedErrors[$i] }103 $acutalPostion = $err.Extent.StartScriptPosition.Offset104 if ( $CheckColumnNumber ) { $acutalPostion = $err.Extent.StartScriptPosition.ColumnNumber }105 It "Error position (iteration:$i)" -Pending:$SkipAndCheckRuntimeError { $acutalPostion | Should -Be $expectedOffsets[$i] }106 }107 }108}109 110function Flatten-Ast111{112 [CmdletBinding()]113 param([System.Management.Automation.Language.Ast] $ast)114 115 $ast116 $ast | gm -type property | Where-Object { ($prop = $_.Name) -ne 'Parent' } | ForEach-Object {117 $ast.$prop | Where-Object { $_ -is [System.Management.Automation.Language.Ast] } | ForEach-Object { Flatten-Ast $_ }118 }119}120 121function Test-ErrorStmt122{123 param([string]$src, [string]$errorStmtExtent)124 $a = $args125 Context "Error Statement expected: <<$src>>" {126 $ast = Get-ParseResults $src -Ast127 $asts = @(Flatten-Ast $ast.EndBlock.Statements[0])128 129 It 'Type is ErrorStatementAst' { $asts[0] | Should BeOfType System.Management.Automation.Language.ErrorStatementAst }130 It "`$asts.count" { $asts.Count | Should -Be ($a.Count + 1) }131 It "`$asts[0].Extent.Text" { $asts[0].Extent.Text | Should -Be $errorStmtExtent }132 for ($i = 0; $i -lt $a.Count; ++$i)133 {134 It "`$asts[$($i + 1)].Extent.Text" { $asts[$i + 1].Extent.Text | Should -Be $a[$i] }135 }136 }137}138 139function Test-Ast140{141 param([string]$src)142 $a = $args143 $ast = Get-ParseResults $src -Ast144 $asts = @(Flatten-Ast $ast)145 Context "Ast Validation: <<$src>>" {146 It "`$asts.count" { $asts.Count | Should -Be $a.Count }147 for ($i = 0; $i -lt $a.Count; ++$i)148 {149 It "`$asts[$i].Extent.Text" { $asts[$i].Extent.Text | Should -Be $a[$i] }150 }151 }152}153 154## ErrorStatement is special for SwitchStatement155 function Test-ErrorStmtForSwitchFlag156 {157 param([string]$src, [string]$flagName)158 $a = $args159 $ast = Get-ParseResults $src -Ast160 $ast = $ast.EndBlock.Statements[0]161 Context "Ast Validation: <<$src>>" {162 $ast | Should BeOfType System.Management.Automation.Language.ErrorStatementAst163 $ast.Flags.ContainsKey($flagName) | Should -BeTrue164 165 $asts = @(Flatten-Ast $ast.Flags[$flagName].Item2)166 167 $asts.Count | Should -Be $a.Count168 for ($i = 0; $i -lt $a.Count; ++$i)169 {170 $asts[$i].Extent.Text | Should -Be $a[$i]171 }172 }173 }174 175Export-ModuleMember -Function Test-ErrorStmt, Test-Ast, ShouldBeParseError, Get-ParseResults, Get-RuntimeError, Test-ErrorStmtForSwitchFlag176 