Add support for detecting and updating splatted parameters (#68)
* Splatted parameter support (part 1) * Added unit test support for splatted parameter detection * Fixed failing unit test from missing property * Added splatted parameter example scripts * Removed warnings for splatted parameter detection * Added matched az upgraded sample scripts * Fixed off-by-one bug and updated unit tests * Added support for splatting with ordered hashtable
This commit is contained in:
Родитель
f0f367f33e
Коммит
69d88f7dca
|
@ -0,0 +1,25 @@
|
|||
# Original source code: https://github.com/Azure/azure-docs-powershell-samples/blob/a513b6fceae51aaea1daaa8edd4d6fc66590d172/virtual-machine/create-vm-detailed/create-windows-vm-quick.ps1
|
||||
# Variables for common values
|
||||
$resourceGroup = "myResourceGroup"
|
||||
$location = "westeurope"
|
||||
$vmName = "myVM"
|
||||
|
||||
# Create user object
|
||||
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
|
||||
|
||||
# Create a resource group
|
||||
New-AzResourceGroup -Name $resourceGroup -Location $location
|
||||
|
||||
# Create a virtual machine
|
||||
# use splatted params
|
||||
$virtualMachineParams = @{
|
||||
Location = $location
|
||||
Image = "Win2016Datacenter"
|
||||
VirtualNetworkName = "myVnet"
|
||||
SubnetName = "mySubnet"
|
||||
SecurityGroupName = "myNetworkSecurityGroup"
|
||||
PublicIpAddressName = "myPublicIp"
|
||||
Credential = $cred
|
||||
OpenPorts = 3389
|
||||
}
|
||||
New-AzVM @virtualMachineParams -ResourceGroupName $resourceGroup -Name $vmName
|
|
@ -0,0 +1,25 @@
|
|||
# Original source code: https://github.com/Azure/azure-docs-powershell-samples/blob/a513b6fceae51aaea1daaa8edd4d6fc66590d172/virtual-machine/create-vm-detailed/create-windows-vm-quick.ps1
|
||||
# Variables for common values
|
||||
$resourceGroup = "myResourceGroup"
|
||||
$location = "westeurope"
|
||||
$vmName = "myVM"
|
||||
|
||||
# Create user object
|
||||
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
|
||||
|
||||
# Create a resource group
|
||||
New-AzResourceGroup -Name $resourceGroup -Location $location
|
||||
|
||||
# Create a virtual machine
|
||||
# use splatted params (keys are wrapped with quotes)
|
||||
$virtualMachineParams = @{
|
||||
"Location" = $location
|
||||
"Image" = "Win2016Datacenter"
|
||||
"VirtualNetworkName" = "myVnet"
|
||||
"SubnetName" = "mySubnet"
|
||||
"SecurityGroupName" = "myNetworkSecurityGroup"
|
||||
"PublicIpAddressName" = "myPublicIp"
|
||||
"Credential" = $cred
|
||||
"OpenPorts" = 3389
|
||||
}
|
||||
New-AzVM @virtualMachineParams -ResourceGroupName $resourceGroup -Name $vmName
|
|
@ -0,0 +1,25 @@
|
|||
# Original source code: https://github.com/Azure/azure-docs-powershell-samples/blob/a513b6fceae51aaea1daaa8edd4d6fc66590d172/virtual-machine/create-vm-detailed/create-windows-vm-quick.ps1
|
||||
# Variables for common values
|
||||
$resourceGroup = "myResourceGroup"
|
||||
$location = "westeurope"
|
||||
$vmName = "myVM"
|
||||
|
||||
# Create user object
|
||||
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
|
||||
|
||||
# Create a resource group
|
||||
New-AzResourceGroup -Name $resourceGroup -Location $location
|
||||
|
||||
# Create a virtual machine
|
||||
# use splatted params
|
||||
$virtualMachineParams = [ordered]@{
|
||||
Location = $location
|
||||
Image = "Win2016Datacenter"
|
||||
VirtualNetworkName = "myVnet"
|
||||
SubnetName = "mySubnet"
|
||||
SecurityGroupName = "myNetworkSecurityGroup"
|
||||
PublicIpAddressName = "myPublicIp"
|
||||
Credential = $cred
|
||||
OpenPorts = 3389
|
||||
}
|
||||
New-AzVM @virtualMachineParams -ResourceGroupName $resourceGroup -Name $vmName
|
|
@ -0,0 +1,25 @@
|
|||
# Original source code: https://github.com/Azure/azure-docs-powershell-samples/blob/a513b6fceae51aaea1daaa8edd4d6fc66590d172/virtual-machine/create-vm-detailed/create-windows-vm-quick.ps1
|
||||
# Variables for common values
|
||||
$resourceGroup = "myResourceGroup"
|
||||
$location = "westeurope"
|
||||
$vmName = "myVM"
|
||||
|
||||
# Create user object
|
||||
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
|
||||
|
||||
# Create a resource group
|
||||
New-AzureRmResourceGroup -Name $resourceGroup -Location $location
|
||||
|
||||
# Create a virtual machine
|
||||
# use splatted params
|
||||
$virtualMachineParams = @{
|
||||
Location = $location
|
||||
ImageName = "Win2016Datacenter"
|
||||
VirtualNetworkName = "myVnet"
|
||||
SubnetName = "mySubnet"
|
||||
SecurityGroupName = "myNetworkSecurityGroup"
|
||||
PublicIpAddressName = "myPublicIp"
|
||||
Credential = $cred
|
||||
OpenPorts = 3389
|
||||
}
|
||||
New-AzureRmVM @virtualMachineParams -ResourceGroupName $resourceGroup -Name $vmName
|
|
@ -0,0 +1,25 @@
|
|||
# Original source code: https://github.com/Azure/azure-docs-powershell-samples/blob/a513b6fceae51aaea1daaa8edd4d6fc66590d172/virtual-machine/create-vm-detailed/create-windows-vm-quick.ps1
|
||||
# Variables for common values
|
||||
$resourceGroup = "myResourceGroup"
|
||||
$location = "westeurope"
|
||||
$vmName = "myVM"
|
||||
|
||||
# Create user object
|
||||
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
|
||||
|
||||
# Create a resource group
|
||||
New-AzureRmResourceGroup -Name $resourceGroup -Location $location
|
||||
|
||||
# Create a virtual machine
|
||||
# use splatted params (keys are wrapped with quotes)
|
||||
$virtualMachineParams = @{
|
||||
"Location" = $location
|
||||
"ImageName" = "Win2016Datacenter"
|
||||
"VirtualNetworkName" = "myVnet"
|
||||
"SubnetName" = "mySubnet"
|
||||
"SecurityGroupName" = "myNetworkSecurityGroup"
|
||||
"PublicIpAddressName" = "myPublicIp"
|
||||
"Credential" = $cred
|
||||
"OpenPorts" = 3389
|
||||
}
|
||||
New-AzureRmVM @virtualMachineParams -ResourceGroupName $resourceGroup -Name $vmName
|
|
@ -0,0 +1,25 @@
|
|||
# Original source code: https://github.com/Azure/azure-docs-powershell-samples/blob/a513b6fceae51aaea1daaa8edd4d6fc66590d172/virtual-machine/create-vm-detailed/create-windows-vm-quick.ps1
|
||||
# Variables for common values
|
||||
$resourceGroup = "myResourceGroup"
|
||||
$location = "westeurope"
|
||||
$vmName = "myVM"
|
||||
|
||||
# Create user object
|
||||
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
|
||||
|
||||
# Create a resource group
|
||||
New-AzureRmResourceGroup -Name $resourceGroup -Location $location
|
||||
|
||||
# Create a virtual machine
|
||||
# use splatted params
|
||||
$virtualMachineParams = [ordered]@{
|
||||
Location = $location
|
||||
ImageName = "Win2016Datacenter"
|
||||
VirtualNetworkName = "myVnet"
|
||||
SubnetName = "mySubnet"
|
||||
SecurityGroupName = "myNetworkSecurityGroup"
|
||||
PublicIpAddressName = "myPublicIp"
|
||||
Credential = $cred
|
||||
OpenPorts = 3389
|
||||
}
|
||||
New-AzureRmVM @virtualMachineParams -ResourceGroupName $resourceGroup -Name $vmName
|
|
@ -45,7 +45,6 @@ class CommandReferenceParameter
|
|||
[System.String] $FileName
|
||||
[System.String] $FullPath
|
||||
[System.String] $Name
|
||||
[System.String] $Value
|
||||
[System.Int32] $StartLine
|
||||
[System.Int32] $StartColumn
|
||||
[System.Int32] $EndLine
|
||||
|
@ -91,7 +90,7 @@ Enum UpgradeStepType
|
|||
Enum PlanResultReasonCode
|
||||
{
|
||||
ReadyToUpgrade = 0
|
||||
WarningSplattedParameters = 1
|
||||
WarningSplattedParameters = 1 # deprecated
|
||||
ErrorNoUpgradeAlias = 2
|
||||
ErrorNoModuleSpecMatch = 3
|
||||
ErrorParameterNotFound = 4
|
||||
|
|
|
@ -26,8 +26,11 @@ function Find-CmdletsInFile
|
|||
)
|
||||
Process
|
||||
{
|
||||
# constants
|
||||
$matchPattern = "(\b[a-zA-z]+-[a-zA-z]+\b)"
|
||||
$cmdletRegex = New-Object System.Text.RegularExpressions.Regex($matchPattern)
|
||||
$doubleQuoteCharacter = '"'
|
||||
$singleQuoteCharacter = ''''
|
||||
$orderedTypeName = 'ordered'
|
||||
|
||||
# ref output vars
|
||||
$parserErrors = $null
|
||||
|
@ -47,10 +50,60 @@ function Find-CmdletsInFile
|
|||
}
|
||||
}
|
||||
|
||||
$predicate = { param($astObject) $astObject -is [System.Management.Automation.Language.CommandAst] }
|
||||
# search for variable assignment statements
|
||||
# the goal here is to build a table with the hastable variable sets (if any are present), to support splatted parameter names.
|
||||
$recurse = $true
|
||||
$assignmentPredicate = { param($astObject) $astObject -is [System.Management.Automation.Language.AssignmentStatementAst] }
|
||||
$assignmentAstNodes = $rootAstNode.FindAll($assignmentPredicate, $recurse)
|
||||
$hashtableVariables = New-Object -TypeName 'System.Collections.Generic.Dictionary[System.String, System.Collections.Generic.List[System.Management.Automation.Language.StringConstantExpressionAst]]'
|
||||
|
||||
$commandAstNodes = $rootAstNode.FindAll($predicate, $recurse)
|
||||
for ([int]$i = 0; $i -lt $assignmentAstNodes.Count; $i++)
|
||||
{
|
||||
$currentVarAstNode = $assignmentAstNodes[$i]
|
||||
|
||||
# is the right hand side of the expression statement a hashtable node?
|
||||
if ($currentVarAstNode.Right.Expression -is [System.Management.Automation.Language.HashtableAst])
|
||||
{
|
||||
# capture the hashtable variable name
|
||||
$htVariableName = $currentVarAstNode.Left.VariablePath.UserPath
|
||||
$hashtableVariables[$htVariableName] = New-Object -TypeName 'System.Collections.Generic.List[System.Management.Automation.Language.StringConstantExpressionAst]'
|
||||
|
||||
# capture the hashtable key name extents.
|
||||
# -- the tuple's .Item1 contains the key name AST (which may represent a splatted parameter name).
|
||||
# -- the tuple's .Item2 contains the key value AST (we dont need to capture this)
|
||||
# -- also make sure to only grab hashtable key names that come from ConstantExpressionAst (to avoid unsupported subexpression keyname scenarios).
|
||||
foreach ($expressionAst in $currentVarAstNode.Right.Expression.KeyValuePairs)
|
||||
{
|
||||
if ($expressionAst.Item1 -is [System.Management.Automation.Language.StringConstantExpressionAst])
|
||||
{
|
||||
$hashtableVariables[$htVariableName].Add($expressionAst.Item1)
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($currentVarAstNode.Right.Expression -is [System.Management.Automation.Language.ConvertExpressionAst] `
|
||||
-and $currentVarAstNode.Right.Expression.Type.TypeName.FullName -eq $orderedTypeName `
|
||||
-and $currentVarAstNode.Right.Expression.Child -is [System.Management.Automation.Language.HashtableAst])
|
||||
{
|
||||
# same as the above 'if' condition case, but special handling for [ordered] hashtable objects.
|
||||
# we have to check the .Child [HashtableAst] of the ConvertExpressionAst.
|
||||
|
||||
$htVariableName = $currentVarAstNode.Left.VariablePath.UserPath
|
||||
$hashtableVariables[$htVariableName] = New-Object -TypeName 'System.Collections.Generic.List[System.Management.Automation.Language.StringConstantExpressionAst]'
|
||||
|
||||
foreach ($expressionAst in $currentVarAstNode.Right.Expression.Child.KeyValuePairs)
|
||||
{
|
||||
if ($expressionAst.Item1 -is [System.Management.Automation.Language.StringConstantExpressionAst])
|
||||
{
|
||||
$hashtableVariables[$htVariableName].Add($expressionAst.Item1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# search for command statements
|
||||
$commandPredicate = { param($astObject) $astObject -is [System.Management.Automation.Language.CommandAst] }
|
||||
$commandAstNodes = $rootAstNode.FindAll($commandPredicate, $recurse)
|
||||
$cmdletRegex = New-Object System.Text.RegularExpressions.Regex($matchPattern)
|
||||
|
||||
for ([int]$i = 0; $i -lt $commandAstNodes.Count; $i++)
|
||||
{
|
||||
|
@ -86,32 +139,17 @@ function Find-CmdletsInFile
|
|||
{
|
||||
$paramRef = New-Object -TypeName CommandReferenceParameter
|
||||
|
||||
# substring to cut off the dash (-) character we dont need
|
||||
$paramRef.Name = $currentAstNodeCmdElement.Extent.Text.Substring(1)
|
||||
|
||||
# check for the parameter value.
|
||||
# if this is the last element in the list, or the next item is also a
|
||||
# parameter, then this parameter has no value (switch parameter)
|
||||
|
||||
if ($j -eq ($currentAstNode.CommandElements.Count -1) `
|
||||
-or $currentAstNode.CommandElements[($j + 1)] -is [System.Management.Automation.Language.CommandParameterAst])
|
||||
{
|
||||
# switch param (no value)
|
||||
$paramRef.Value = $null
|
||||
}
|
||||
else
|
||||
{
|
||||
# regular param (has value)
|
||||
$paramRef.Value = $currentAstNode.CommandElements[($j + 1)].Extent.Text
|
||||
}
|
||||
|
||||
# grab the parameter name with no dash value
|
||||
# the extent offsets here include the dash, so add +1 to the starting values
|
||||
# construct the parameter object with location details
|
||||
$paramRef.Name = $currentAstNodeCmdElement.ParameterName
|
||||
$paramRef.FullPath = $cmdletRef.FullPath
|
||||
$paramRef.FileName = $cmdletRef.FileName
|
||||
$paramRef.StartLine = $currentAstNodeCmdElement.Extent.StartLineNumber
|
||||
$paramRef.StartColumn = $currentAstNodeCmdElement.Extent.StartColumnNumber
|
||||
$paramRef.StartColumn = ($currentAstNodeCmdElement.Extent.StartColumnNumber + 1)
|
||||
$paramRef.EndLine = $currentAstNodeCmdElement.Extent.EndLineNumber
|
||||
$paramRef.EndPosition = $currentAstNodeCmdElement.Extent.EndColumnNumber
|
||||
$paramRef.StartOffset = $currentAstNodeCmdElement.Extent.StartOffset
|
||||
$paramRef.StartOffset = ($currentAstNodeCmdElement.Extent.StartOffset + 1)
|
||||
$paramRef.EndOffset = $currentAstNodeCmdElement.Extent.EndOffset
|
||||
$paramRef.Location = "{0}:{1}:{2}" -f $paramRef.FileName, $paramRef.StartLine, $paramRef.StartColumn
|
||||
|
||||
|
@ -121,6 +159,49 @@ function Find-CmdletsInFile
|
|||
-and $currentAstNodeCmdElement.Splatted -eq $true)
|
||||
{
|
||||
$cmdletRef.HasSplattedArguments = $true
|
||||
|
||||
# grab the splatted parameter name without the '@' character prefix.
|
||||
# we can then look this up in our known hashtable variables table.
|
||||
$hashtableVariableName = $currentAstNodeCmdElement.VariablePath.UserPath
|
||||
|
||||
if ($hashtableVariables.ContainsKey($hashtableVariableName))
|
||||
{
|
||||
foreach ($splattedParameter in $hashtableVariables[$hashtableVariableName])
|
||||
{
|
||||
$paramRef = New-Object -TypeName CommandReferenceParameter
|
||||
|
||||
# add new parameter, similar to above, however a hashtable key name is the parameter name.
|
||||
$paramRef.Name = $splattedParameter.Value
|
||||
$paramRef.FullPath = $cmdletRef.FullPath
|
||||
$paramRef.FileName = $cmdletRef.FileName
|
||||
|
||||
if ($splattedParameter.Extent.Text[0] -ne $doubleQuoteCharacter -and $splattedParameter.Extent.Text[0] -ne $singleQuoteCharacter)
|
||||
{
|
||||
# normal hash table key (not wrapped in quote characters)
|
||||
$paramRef.StartLine = $splattedParameter.Extent.StartLineNumber
|
||||
$paramRef.StartColumn = $splattedParameter.Extent.StartColumnNumber
|
||||
$paramRef.EndLine = $splattedParameter.Extent.EndLineNumber
|
||||
$paramRef.EndPosition = $splattedParameter.Extent.EndColumnNumber
|
||||
$paramRef.StartOffset = $splattedParameter.Extent.StartOffset
|
||||
$paramRef.EndOffset = $splattedParameter.Extent.EndOffset
|
||||
}
|
||||
else
|
||||
{
|
||||
# hash table key wrapped in quotes
|
||||
# use special offset handling to account for quote wrapper characters.
|
||||
$paramRef.StartLine = $splattedParameter.Extent.StartLineNumber
|
||||
$paramRef.StartColumn = ($splattedParameter.Extent.StartColumnNumber + 1)
|
||||
$paramRef.EndLine = $splattedParameter.Extent.EndLineNumber
|
||||
$paramRef.EndPosition = ($splattedParameter.Extent.EndColumnNumber - 1)
|
||||
$paramRef.StartOffset = ($splattedParameter.Extent.StartOffset + 1)
|
||||
$paramRef.EndOffset = ($splattedParameter.Extent.EndOffset - 1)
|
||||
}
|
||||
|
||||
$paramRef.Location = "{0}:{1}:{2}" -f $paramRef.FileName, $paramRef.StartLine, $paramRef.StartColumn
|
||||
|
||||
$cmdletRef.Parameters.Add($paramRef)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,12 +60,12 @@ function Invoke-ModuleUpgradeStep
|
|||
|
||||
# safety check
|
||||
# ensure that the file offsets are an exact match.
|
||||
Confirm-StringBuilderSubstring -FileContent $FileContent -Substring ("-{0}" -f $Step.Original) `
|
||||
Confirm-StringBuilderSubstring -FileContent $FileContent -Substring $Step.Original `
|
||||
-StartOffset $Step.SourceCommandParameter.StartOffset -EndOffset $Step.SourceCommandParameter.EndOffset
|
||||
|
||||
# replacement code
|
||||
$null = $FileContent.Remove($Step.SourceCommandParameter.StartOffset, ($Step.SourceCommandParameter.EndOffset - $Step.SourceCommandParameter.StartOffset));
|
||||
$null = $FileContent.Insert($Step.SourceCommandParameter.StartOffset, ("-{0}" -f $Step.Replacement));
|
||||
$null = $FileContent.Insert($Step.SourceCommandParameter.StartOffset, $Step.Replacement);
|
||||
}
|
||||
default
|
||||
{
|
||||
|
|
|
@ -244,20 +244,10 @@ function New-AzUpgradeModulePlan
|
|||
$cmdletUpgrade.StartOffset = $rmCmdlet.StartOffset
|
||||
$cmdletUpgrade.Location = $rmCmdlet.Location
|
||||
|
||||
if ($rmCmdlet.HasSplattedArguments -eq $false)
|
||||
{
|
||||
$cmdletUpgrade.PlanResultReason = "Command can be automatically upgraded."
|
||||
$cmdletUpgrade.PlanResult = [PlanResultReasonCode]::ReadyToUpgrade
|
||||
$cmdletUpgrade.PlanSeverity = [DiagnosticSeverity]::Information
|
||||
$planSteps.Add($cmdletUpgrade)
|
||||
}
|
||||
else
|
||||
{
|
||||
$cmdletUpgrade.PlanResultReason = "Cmdlet invocation uses splatted parameters. Consider unrolling to allow automated parameter upgrade checks."
|
||||
$cmdletUpgrade.PlanResult = [PlanResultReasonCode]::WarningSplattedParameters
|
||||
$cmdletUpgrade.PlanSeverity = [DiagnosticSeverity]::Warning
|
||||
$planWarningSteps.Add($cmdletUpgrade)
|
||||
}
|
||||
$cmdletUpgrade.PlanResultReason = "Command can be automatically upgraded."
|
||||
$cmdletUpgrade.PlanResult = [PlanResultReasonCode]::ReadyToUpgrade
|
||||
$cmdletUpgrade.PlanSeverity = [DiagnosticSeverity]::Information
|
||||
$planSteps.Add($cmdletUpgrade)
|
||||
|
||||
# check if parameters need to be updated
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
$splattedParams = @{
|
||||
TargetName = $TargetName
|
||||
Count = 5
|
||||
IPv4 = $true
|
||||
}
|
||||
|
||||
Test-Connection @splattedParams
|
|
@ -0,0 +1,7 @@
|
|||
# example 1: hashtable splatted arguments (supported)
|
||||
$splattedParams = @{
|
||||
TargetName = $TargetName
|
||||
Count = 5
|
||||
IPv4 = $true
|
||||
}
|
||||
Test-Connection @splattedParams -Delay 3
|
|
@ -0,0 +1,7 @@
|
|||
# example 2: hashtable splatted arguments with quote characters around key names (supported)
|
||||
$splattedParams = @{
|
||||
"TargetName" = $TargetName
|
||||
"Count" = 5
|
||||
'IPv4' = $true
|
||||
}
|
||||
Test-Connection @splattedParams -Delay 3
|
|
@ -0,0 +1,10 @@
|
|||
# example 3: hashtable splatted arguments with variable expressions in keynames (not supported, but should not break parser)
|
||||
$keyName1 = "TargetName"
|
||||
$keyName2 = "Count"
|
||||
$keyName3 = "IPv4"
|
||||
$splattedParams = @{
|
||||
"$keyName1" = $TargetName
|
||||
"$($keyName2)" = 5
|
||||
$keyName3 = $true
|
||||
}
|
||||
Test-Connection @splattedParams -Delay 3
|
|
@ -0,0 +1,3 @@
|
|||
# example 4: array splatted arguments (not supported, but should not break parser)
|
||||
$ArraySplattedArguments = "test.txt", "test2.txt"
|
||||
Copy-Item @ArraySplattedArguments -WhatIf
|
|
@ -0,0 +1,4 @@
|
|||
# example 5: hashtable splatted arguments are used, but not defined in the file.
|
||||
# they would be from another scope, so this scenario is also not supported.
|
||||
|
||||
Test-Connection @splattedParams -Delay 3
|
|
@ -0,0 +1,7 @@
|
|||
# example 1: hashtable splatted arguments with an ordered hashtable (supported)
|
||||
$splattedParams = [ordered]@{
|
||||
TargetName = $TargetName
|
||||
Count = 5
|
||||
IPv4 = $true
|
||||
}
|
||||
Test-Connection @splattedParams -Delay 3
|
|
@ -29,30 +29,27 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$results[0].Parameters.Count | Should Be 3
|
||||
$results[0].Parameters[0].Name | Should Be "TargetName"
|
||||
$results[0].Parameters[0].Value | Should Be "`$TargetName"
|
||||
$results[0].Parameters[0].StartLine | Should Be 1
|
||||
$results[0].Parameters[0].StartColumn | Should Be 17
|
||||
$results[0].Parameters[0].StartColumn | Should Be 18
|
||||
$results[0].Parameters[0].EndLine | Should Be 1
|
||||
$results[0].Parameters[0].EndPosition | Should Be 28
|
||||
$results[0].Parameters[0].StartOffset | Should Be 16
|
||||
$results[0].Parameters[0].StartOffset | Should Be 17
|
||||
$results[0].Parameters[0].EndOffset | Should Be 27
|
||||
|
||||
$results[0].Parameters[1].Name | Should Be "IPv4"
|
||||
$results[0].Parameters[1].Value | Should Be ([System.String]::Empty)
|
||||
$results[0].Parameters[1].StartLine | Should Be 1
|
||||
$results[0].Parameters[1].StartColumn | Should Be 41
|
||||
$results[0].Parameters[1].StartColumn | Should Be 42
|
||||
$results[0].Parameters[1].EndLine | Should Be 1
|
||||
$results[0].Parameters[1].EndPosition | Should Be 46
|
||||
$results[0].Parameters[1].StartOffset | Should Be 40
|
||||
$results[0].Parameters[1].StartOffset | Should Be 41
|
||||
$results[0].Parameters[1].EndOffset | Should Be 45
|
||||
|
||||
$results[0].Parameters[2].Name | Should Be "Count"
|
||||
$results[0].Parameters[2].Value | Should Be "5"
|
||||
$results[0].Parameters[2].StartLine | Should Be 1
|
||||
$results[0].Parameters[2].StartColumn | Should Be 47
|
||||
$results[0].Parameters[2].StartColumn | Should Be 48
|
||||
$results[0].Parameters[2].EndLine | Should Be 1
|
||||
$results[0].Parameters[2].EndPosition | Should Be 53
|
||||
$results[0].Parameters[2].StartOffset | Should Be 46
|
||||
$results[0].Parameters[2].StartOffset | Should Be 47
|
||||
$results[0].Parameters[2].EndOffset | Should Be 52
|
||||
}
|
||||
It 'Should be able to find cmdlets used in MultipleCommands script file' {
|
||||
|
@ -77,30 +74,27 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$results[0].Parameters.Count | Should Be 3
|
||||
$results[0].Parameters[0].Name | Should Be "TargetName"
|
||||
$results[0].Parameters[0].Value | Should Be "`$TargetName"
|
||||
$results[0].Parameters[0].StartLine | Should Be 1
|
||||
$results[0].Parameters[0].StartColumn | Should Be 17
|
||||
$results[0].Parameters[0].StartColumn | Should Be 18
|
||||
$results[0].Parameters[0].EndLine | Should Be 1
|
||||
$results[0].Parameters[0].EndPosition | Should Be 28
|
||||
$results[0].Parameters[0].StartOffset | Should Be 16
|
||||
$results[0].Parameters[0].StartOffset | Should Be 17
|
||||
$results[0].Parameters[0].EndOffset | Should Be 27
|
||||
|
||||
$results[0].Parameters[1].Name | Should Be "IPv4"
|
||||
$results[0].Parameters[1].Value | Should Be ([System.String]::Empty)
|
||||
$results[0].Parameters[1].StartLine | Should Be 1
|
||||
$results[0].Parameters[1].StartColumn | Should Be 41
|
||||
$results[0].Parameters[1].StartColumn | Should Be 42
|
||||
$results[0].Parameters[1].EndLine | Should Be 1
|
||||
$results[0].Parameters[1].EndPosition | Should Be 46
|
||||
$results[0].Parameters[1].StartOffset | Should Be 40
|
||||
$results[0].Parameters[1].StartOffset | Should Be 41
|
||||
$results[0].Parameters[1].EndOffset | Should Be 45
|
||||
|
||||
$results[0].Parameters[2].Name | Should Be "Count"
|
||||
$results[0].Parameters[2].Value | Should Be "5"
|
||||
$results[0].Parameters[2].StartLine | Should Be 1
|
||||
$results[0].Parameters[2].StartColumn | Should Be 47
|
||||
$results[0].Parameters[2].StartColumn | Should Be 48
|
||||
$results[0].Parameters[2].EndLine | Should Be 1
|
||||
$results[0].Parameters[2].EndPosition | Should Be 53
|
||||
$results[0].Parameters[2].StartOffset | Should Be 46
|
||||
$results[0].Parameters[2].StartOffset | Should Be 47
|
||||
$results[0].Parameters[2].EndOffset | Should Be 52
|
||||
|
||||
$results[1].StartLine | Should Be 3
|
||||
|
@ -113,12 +107,11 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$results[1].Parameters.Count | Should Be 1
|
||||
$results[1].Parameters[0].Name | Should Be "Path"
|
||||
$results[1].Parameters[0].Value | Should Be "`"C:\users\user`""
|
||||
$results[1].Parameters[0].StartLine | Should Be 3
|
||||
$results[1].Parameters[0].StartColumn | Should Be 15
|
||||
$results[1].Parameters[0].StartColumn | Should Be 16
|
||||
$results[1].Parameters[0].EndLine | Should Be 3
|
||||
$results[1].Parameters[0].EndPosition | Should Be 20
|
||||
$results[1].Parameters[0].StartOffset | Should Be 72
|
||||
$results[1].Parameters[0].StartOffset | Should Be 73
|
||||
$results[1].Parameters[0].EndOffset | Should Be 77
|
||||
|
||||
$results[2].StartLine | Should Be 5
|
||||
|
@ -149,30 +142,27 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$results[0].Parameters.Count | Should Be 3
|
||||
$results[0].Parameters[0].Name | Should Be "TargetName"
|
||||
$results[0].Parameters[0].Value | Should Be "`$TargetName"
|
||||
$results[0].Parameters[0].StartLine | Should Be 25
|
||||
$results[0].Parameters[0].StartColumn | Should Be 25
|
||||
$results[0].Parameters[0].StartColumn | Should Be 26
|
||||
$results[0].Parameters[0].EndLine | Should Be 25
|
||||
$results[0].Parameters[0].EndPosition | Should Be 36
|
||||
$results[0].Parameters[0].StartOffset | Should Be 469
|
||||
$results[0].Parameters[0].StartOffset | Should Be 470
|
||||
$results[0].Parameters[0].EndOffset | Should Be 480
|
||||
|
||||
$results[0].Parameters[1].Name | Should Be "IPv4"
|
||||
$results[0].Parameters[1].Value | Should Be ([System.String]::Empty)
|
||||
$results[0].Parameters[1].StartLine | Should Be 25
|
||||
$results[0].Parameters[1].StartColumn | Should Be 49
|
||||
$results[0].Parameters[1].StartColumn | Should Be 50
|
||||
$results[0].Parameters[1].EndLine | Should Be 25
|
||||
$results[0].Parameters[1].EndPosition | Should Be 54
|
||||
$results[0].Parameters[1].StartOffset | Should Be 493
|
||||
$results[0].Parameters[1].StartOffset | Should Be 494
|
||||
$results[0].Parameters[1].EndOffset | Should Be 498
|
||||
|
||||
$results[0].Parameters[2].Name | Should Be "Count"
|
||||
$results[0].Parameters[2].Value | Should Be "5"
|
||||
$results[0].Parameters[2].StartLine | Should Be 25
|
||||
$results[0].Parameters[2].StartColumn | Should Be 55
|
||||
$results[0].Parameters[2].StartColumn | Should Be 56
|
||||
$results[0].Parameters[2].EndLine | Should Be 25
|
||||
$results[0].Parameters[2].EndPosition | Should Be 61
|
||||
$results[0].Parameters[2].StartOffset | Should Be 499
|
||||
$results[0].Parameters[2].StartOffset | Should Be 500
|
||||
$results[0].Parameters[2].EndOffset | Should Be 505
|
||||
}
|
||||
It 'Should be able to find cmdlets used in MultipleCommands function file' {
|
||||
|
@ -216,39 +206,35 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
$results[0].Parameters.Count | Should Be 4
|
||||
|
||||
$results[0].Parameters[0].Name | Should Be "TargetName"
|
||||
$results[0].Parameters[0].Value | Should Be "`$TargetName"
|
||||
$results[0].Parameters[0].StartLine | Should Be 27
|
||||
$results[0].Parameters[0].StartColumn | Should Be 29
|
||||
$results[0].Parameters[0].StartColumn | Should Be 30
|
||||
$results[0].Parameters[0].EndLine | Should Be 27
|
||||
$results[0].Parameters[0].EndPosition | Should Be 40
|
||||
$results[0].Parameters[0].StartOffset | Should Be 497
|
||||
$results[0].Parameters[0].StartOffset | Should Be 498
|
||||
$results[0].Parameters[0].EndOffset | Should Be 508
|
||||
|
||||
$results[0].Parameters[1].Name | Should Be "IPv4"
|
||||
$results[0].Parameters[1].Value | Should Be ([System.String]::Empty)
|
||||
$results[0].Parameters[1].StartLine | Should Be 28
|
||||
$results[0].Parameters[1].StartColumn | Should Be 17
|
||||
$results[0].Parameters[1].StartColumn | Should Be 18
|
||||
$results[0].Parameters[1].EndLine | Should Be 28
|
||||
$results[0].Parameters[1].EndPosition | Should Be 22
|
||||
$results[0].Parameters[1].StartOffset | Should Be 540
|
||||
$results[0].Parameters[1].StartOffset | Should Be 541
|
||||
$results[0].Parameters[1].EndOffset | Should Be 545
|
||||
|
||||
$results[0].Parameters[2].Name | Should Be "Count"
|
||||
$results[0].Parameters[2].Value | Should Be "(Get-RequestCount -Test `"Value`")"
|
||||
$results[0].Parameters[2].StartLine | Should Be 29
|
||||
$results[0].Parameters[2].StartColumn | Should Be 17
|
||||
$results[0].Parameters[2].StartColumn | Should Be 18
|
||||
$results[0].Parameters[2].EndLine | Should Be 29
|
||||
$results[0].Parameters[2].EndPosition | Should Be 23
|
||||
$results[0].Parameters[2].StartOffset | Should Be 565
|
||||
$results[0].Parameters[2].StartOffset | Should Be 566
|
||||
$results[0].Parameters[2].EndOffset | Should Be 571
|
||||
|
||||
$results[0].Parameters[3].Name | Should Be "OriginalCommandParam"
|
||||
$results[0].Parameters[3].Value | Should Be "`"Value2`""
|
||||
$results[0].Parameters[3].StartLine | Should Be 30
|
||||
$results[0].Parameters[3].StartColumn | Should Be 17
|
||||
$results[0].Parameters[3].StartColumn | Should Be 18
|
||||
$results[0].Parameters[3].EndLine | Should Be 30
|
||||
$results[0].Parameters[3].EndPosition | Should Be 38
|
||||
$results[0].Parameters[3].StartOffset | Should Be 624
|
||||
$results[0].Parameters[3].StartOffset | Should Be 625
|
||||
$results[0].Parameters[3].EndOffset | Should Be 645
|
||||
|
||||
$results[1].StartLine | Should Be 29
|
||||
|
@ -263,12 +249,11 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
$results[1].Parameters.Count | Should Be 1
|
||||
|
||||
$results[1].Parameters[0].Name | Should Be "Test"
|
||||
$results[1].Parameters[0].Value | Should Be "`"Value`""
|
||||
$results[1].Parameters[0].StartLine | Should Be 29
|
||||
$results[1].Parameters[0].StartColumn | Should Be 42
|
||||
$results[1].Parameters[0].StartColumn | Should Be 43
|
||||
$results[1].Parameters[0].EndLine | Should Be 29
|
||||
$results[1].Parameters[0].EndPosition | Should Be 47
|
||||
$results[1].Parameters[0].StartOffset | Should Be 590
|
||||
$results[1].Parameters[0].StartOffset | Should Be 591
|
||||
$results[1].Parameters[0].EndOffset | Should Be 595
|
||||
}
|
||||
It 'Should be able to find cmdlets used in LineContinuation script file' {
|
||||
|
@ -364,9 +349,9 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
$results[1].CommandName | Should Be "Get-RequestCount"
|
||||
$results[1].HasSplattedArguments | Should Be $false
|
||||
}
|
||||
It 'Should be able to find cmdlets that have splatted parameters' {
|
||||
It 'Should be able to find splatted parameters' {
|
||||
# arrange
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting.ps1"
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting1.ps1"
|
||||
|
||||
# act
|
||||
$results = Find-CmdletsInFile -FilePath $testFile.Path
|
||||
|
@ -374,15 +359,310 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
# assert
|
||||
$results | Should Not Be Null
|
||||
$results.Count | Should Be 1
|
||||
|
||||
$results[0].StartLine | Should Be 7
|
||||
$results[0].StartColumn | Should Be 1
|
||||
$results[0].EndLine | Should Be 7
|
||||
$results[0].EndPosition | Should Be 16
|
||||
$results[0].CommandName | Should Be "Test-Connection"
|
||||
$results[0].HasSplattedArguments | Should Be $true
|
||||
|
||||
# we should have 4 valid parameters here, but order is not guaranteed due to enumeration
|
||||
# over an unsorted dictionary. avoid using an ordered index check for the tests.
|
||||
|
||||
$results[0].Parameters.Count | Should Be 0
|
||||
$expectedParameters = @(
|
||||
[PSCustomObject]@{
|
||||
Name = "TargetName"
|
||||
StartLine = 3
|
||||
StartColumn = 5
|
||||
EndLine = 3
|
||||
EndPosition = 15
|
||||
StartOffset = 81
|
||||
EndOffset = 91
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "Count"
|
||||
StartLine = 4
|
||||
StartColumn = 5
|
||||
EndLine = 4
|
||||
EndPosition = 10
|
||||
StartOffset = 111
|
||||
EndOffset = 116
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "IPv4"
|
||||
StartLine = 5
|
||||
StartColumn = 5
|
||||
EndLine = 5
|
||||
EndPosition = 9
|
||||
StartOffset = 126
|
||||
EndOffset = 130
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "Delay"
|
||||
StartLine = 7
|
||||
StartColumn = 34
|
||||
EndLine = 7
|
||||
EndPosition = 39
|
||||
StartOffset = 176
|
||||
EndOffset = 181
|
||||
}
|
||||
)
|
||||
|
||||
$results[0].Parameters.Count | Should Be $expectedParameters.Count
|
||||
|
||||
foreach ($expectedParam in $expectedParameters)
|
||||
{
|
||||
$paramSearch = $results[0].Parameters | Where-Object -FilterScript { $_.Name -eq $expectedParam.Name }
|
||||
|
||||
$paramSearch | Should Not Be Null
|
||||
$paramSearch.StartLine | Should Be $expectedParam.StartLine
|
||||
$paramSearch.StartColumn | Should Be $expectedParam.StartColumn
|
||||
$paramSearch.EndLine | Should Be $expectedParam.EndLine
|
||||
$paramSearch.EndPosition | Should Be $expectedParam.EndPosition
|
||||
$paramSearch.StartOffset | Should Be $expectedParam.StartOffset
|
||||
$paramSearch.EndOffset | Should Be $expectedParam.EndOffset
|
||||
}
|
||||
}
|
||||
It 'Should be able to find splatted parameters from ordered hashtables' {
|
||||
# arrange
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting6.ps1"
|
||||
|
||||
# act
|
||||
$results = Find-CmdletsInFile -FilePath $testFile.Path
|
||||
|
||||
# assert
|
||||
$results | Should Not Be Null
|
||||
$results.Count | Should Be 1
|
||||
$results[0].StartLine | Should Be 7
|
||||
$results[0].StartColumn | Should Be 1
|
||||
$results[0].EndLine | Should Be 7
|
||||
$results[0].EndPosition | Should Be 16
|
||||
$results[0].CommandName | Should Be "Test-Connection"
|
||||
$results[0].HasSplattedArguments | Should Be $true
|
||||
|
||||
# we should have 4 valid parameters here, but order is not guaranteed due to enumeration
|
||||
# over an unsorted dictionary. avoid using an ordered index check for the tests.
|
||||
|
||||
$expectedParameters = @(
|
||||
[PSCustomObject]@{
|
||||
Name = "TargetName"
|
||||
StartLine = 3
|
||||
StartColumn = 5
|
||||
EndLine = 3
|
||||
EndPosition = 15
|
||||
StartOffset = 116
|
||||
EndOffset = 126
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "Count"
|
||||
StartLine = 4
|
||||
StartColumn = 5
|
||||
EndLine = 4
|
||||
EndPosition = 10
|
||||
StartOffset = 146
|
||||
EndOffset = 151
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "IPv4"
|
||||
StartLine = 5
|
||||
StartColumn = 5
|
||||
EndLine = 5
|
||||
EndPosition = 9
|
||||
StartOffset = 161
|
||||
EndOffset = 165
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "Delay"
|
||||
StartLine = 7
|
||||
StartColumn = 34
|
||||
EndLine = 7
|
||||
EndPosition = 39
|
||||
StartOffset = 211
|
||||
EndOffset = 216
|
||||
}
|
||||
)
|
||||
|
||||
$results[0].Parameters.Count | Should Be $expectedParameters.Count
|
||||
|
||||
foreach ($expectedParam in $expectedParameters)
|
||||
{
|
||||
$paramSearch = $results[0].Parameters | Where-Object -FilterScript { $_.Name -eq $expectedParam.Name }
|
||||
|
||||
$paramSearch | Should Not Be Null
|
||||
$paramSearch.StartLine | Should Be $expectedParam.StartLine
|
||||
$paramSearch.StartColumn | Should Be $expectedParam.StartColumn
|
||||
$paramSearch.EndLine | Should Be $expectedParam.EndLine
|
||||
$paramSearch.EndPosition | Should Be $expectedParam.EndPosition
|
||||
$paramSearch.StartOffset | Should Be $expectedParam.StartOffset
|
||||
$paramSearch.EndOffset | Should Be $expectedParam.EndOffset
|
||||
}
|
||||
}
|
||||
It 'Should be able to find splatted parameters wrapped with quote characters' {
|
||||
# arrange
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting2.ps1"
|
||||
|
||||
# act
|
||||
$results = Find-CmdletsInFile -FilePath $testFile.Path
|
||||
|
||||
# assert
|
||||
$results | Should Not Be Null
|
||||
$results.Count | Should Be 1
|
||||
$results[0].StartLine | Should Be 7
|
||||
$results[0].StartColumn | Should Be 1
|
||||
$results[0].EndLine | Should Be 7
|
||||
$results[0].EndPosition | Should Be 16
|
||||
$results[0].CommandName | Should Be "Test-Connection"
|
||||
$results[0].HasSplattedArguments | Should Be $true
|
||||
|
||||
# we should have 4 valid parameters here, but order is not guaranteed due to enumeration
|
||||
# over an unsorted dictionary. avoid using an ordered index check for the tests.
|
||||
|
||||
# difference here over the first example is the addition of quote characters.
|
||||
# we want to make sure we index/offset at the right locations to account for the quotes.
|
||||
|
||||
$expectedParameters = @(
|
||||
[PSCustomObject]@{
|
||||
Name = "TargetName"
|
||||
StartLine = 3
|
||||
StartColumn = 6
|
||||
EndLine = 3
|
||||
EndPosition = 16
|
||||
StartOffset = 121
|
||||
EndOffset = 131
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "Count"
|
||||
StartLine = 4
|
||||
StartColumn = 6
|
||||
EndLine = 4
|
||||
EndPosition = 11
|
||||
StartOffset = 153
|
||||
EndOffset = 158
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "IPv4"
|
||||
StartLine = 5
|
||||
StartColumn = 6
|
||||
EndLine = 5
|
||||
EndPosition = 10
|
||||
StartOffset = 170
|
||||
EndOffset = 174
|
||||
},
|
||||
[PSCustomObject]@{
|
||||
Name = "Delay"
|
||||
StartLine = 7
|
||||
StartColumn = 34
|
||||
EndLine = 7
|
||||
EndPosition = 39
|
||||
StartOffset = 221
|
||||
EndOffset = 226
|
||||
}
|
||||
)
|
||||
|
||||
$results[0].Parameters.Count | Should Be $expectedParameters.Count
|
||||
|
||||
foreach ($expectedParam in $expectedParameters)
|
||||
{
|
||||
$paramSearch = $results[0].Parameters | Where-Object -FilterScript { $_.Name -eq $expectedParam.Name }
|
||||
|
||||
$paramSearch | Should Not Be Null
|
||||
$paramSearch.StartLine | Should Be $expectedParam.StartLine
|
||||
$paramSearch.StartColumn | Should Be $expectedParam.StartColumn
|
||||
$paramSearch.EndLine | Should Be $expectedParam.EndLine
|
||||
$paramSearch.EndPosition | Should Be $expectedParam.EndPosition
|
||||
$paramSearch.StartOffset | Should Be $expectedParam.StartOffset
|
||||
$paramSearch.EndOffset | Should Be $expectedParam.EndOffset
|
||||
}
|
||||
}
|
||||
It 'Should not detect splatted parameter key names defined using expressions' {
|
||||
# arrange
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting3.ps1"
|
||||
|
||||
# act
|
||||
$results = Find-CmdletsInFile -FilePath $testFile.Path
|
||||
|
||||
# assert
|
||||
$results | Should Not Be Null
|
||||
$results.Count | Should Be 1
|
||||
$results[0].StartLine | Should Be 10
|
||||
$results[0].StartColumn | Should Be 1
|
||||
$results[0].EndLine | Should Be 10
|
||||
$results[0].EndPosition | Should Be 16
|
||||
$results[0].CommandName | Should Be "Test-Connection"
|
||||
|
||||
# this scenario uses key names determined by other expressions.
|
||||
# this is out of scope/unsupported, but should not break the parser.
|
||||
# it should indicate that we have splatted arguments, but only detect the single valid parameter.
|
||||
|
||||
$results[0].HasSplattedArguments | Should Be $true
|
||||
$results[0].Parameters.Count | Should Be 1
|
||||
$results[0].Parameters[0].Name | Should Be "Delay"
|
||||
$results[0].Parameters[0].StartLine | Should Be 10
|
||||
$results[0].Parameters[0].StartColumn | Should Be 34
|
||||
$results[0].Parameters[0].EndLine | Should Be 10
|
||||
$results[0].Parameters[0].EndPosition | Should Be 39
|
||||
$results[0].Parameters[0].StartOffset | Should Be 329
|
||||
$results[0].Parameters[0].EndOffset | Should Be 334
|
||||
}
|
||||
It 'Should not detect positional argument array splatted arguments' {
|
||||
# arrange
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting4.ps1"
|
||||
|
||||
# act
|
||||
$results = Find-CmdletsInFile -FilePath $testFile.Path
|
||||
|
||||
# assert
|
||||
$results | Should Not Be Null
|
||||
$results.Count | Should Be 1
|
||||
$results[0].StartLine | Should Be 3
|
||||
$results[0].StartColumn | Should Be 1
|
||||
$results[0].EndLine | Should Be 3
|
||||
$results[0].EndPosition | Should Be 10
|
||||
$results[0].CommandName | Should Be "Copy-Item"
|
||||
|
||||
# this scenario uses positional argument arrays as splatted parameters.
|
||||
# these are positional arguments (unsupported because they have no key names).
|
||||
# however it should indicate that we have splatted arguments and only detect the single valid parameter.
|
||||
|
||||
$results[0].HasSplattedArguments | Should Be $true
|
||||
$results[0].Parameters.Count | Should Be 1
|
||||
$results[0].Parameters[0].Name | Should Be "WhatIf"
|
||||
$results[0].Parameters[0].StartLine | Should Be 3
|
||||
$results[0].Parameters[0].StartColumn | Should Be 36
|
||||
$results[0].Parameters[0].EndLine | Should Be 3
|
||||
$results[0].Parameters[0].EndPosition | Should Be 42
|
||||
$results[0].Parameters[0].StartOffset | Should Be 170
|
||||
$results[0].Parameters[0].EndOffset | Should Be 176
|
||||
}
|
||||
It 'Should not detect splatted arguments defined outside the file scope' {
|
||||
# arrange
|
||||
$testFile = Resolve-Path -Path ".\Resources\TestFiles\ScriptExample-ParameterSplatting5.ps1"
|
||||
|
||||
# act
|
||||
$results = Find-CmdletsInFile -FilePath $testFile.Path
|
||||
|
||||
# assert
|
||||
$results | Should Not Be Null
|
||||
$results.Count | Should Be 1
|
||||
$results[0].StartLine | Should Be 4
|
||||
$results[0].StartColumn | Should Be 1
|
||||
$results[0].EndLine | Should Be 4
|
||||
$results[0].EndPosition | Should Be 16
|
||||
$results[0].CommandName | Should Be "Test-Connection"
|
||||
|
||||
# this scenario references a hashtable argument that doesn't exist in the scope of the file.
|
||||
# this obviously isn't supported because we can't expand the search beyond the scope of the file.
|
||||
# however it should indicate that we have splatted arguments and only detect the single valid parameter.
|
||||
|
||||
$results[0].HasSplattedArguments | Should Be $true
|
||||
$results[0].Parameters.Count | Should Be 1
|
||||
$results[0].Parameters[0].Name | Should Be "Delay"
|
||||
$results[0].Parameters[0].StartLine | Should Be 4
|
||||
$results[0].Parameters[0].StartColumn | Should Be 34
|
||||
$results[0].Parameters[0].EndLine | Should Be 4
|
||||
$results[0].Parameters[0].EndPosition | Should Be 39
|
||||
$results[0].Parameters[0].StartOffset | Should Be 194
|
||||
$results[0].Parameters[0].EndOffset | Should Be 199
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$step.Location = "test.ps1:3:5"
|
||||
$step.SourceCommandParameter = New-Object -TypeName CommandReferenceParameter
|
||||
$step.SourceCommandParameter.StartOffset = 80
|
||||
$step.SourceCommandParameter.StartOffset = 81
|
||||
$step.SourceCommandParameter.EndOffset = 85
|
||||
|
||||
# act
|
||||
|
@ -105,7 +105,7 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$step.Location = "test.ps1:3:5"
|
||||
$step.SourceCommandParameter = New-Object -TypeName CommandReferenceParameter
|
||||
$step.SourceCommandParameter.StartOffset = 80
|
||||
$step.SourceCommandParameter.StartOffset = 81
|
||||
$step.SourceCommandParameter.EndOffset = 85
|
||||
|
||||
# act
|
||||
|
|
|
@ -179,54 +179,6 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
Assert-VerifiableMock
|
||||
}
|
||||
It 'Should be able to execute plan steps with warning state' {
|
||||
# arrange
|
||||
$step1 = New-Object -TypeName UpgradePlan
|
||||
$step1.FullPath = "C:\mock-file.ps1"
|
||||
$step1.UpgradeType = [UpgradeStepType]::Cmdlet
|
||||
$step1.PlanResult = [PlanResultReasonCode]::ReadyToUpgrade
|
||||
$step1.PlanSeverity = [DiagnosticSeverity]::Information
|
||||
$step1.Location = "mocked-file.ps1:10:5"
|
||||
$step1.Original = "Login-AzureRmAccount"
|
||||
$step1.Replacement = "Login-AzAccount"
|
||||
|
||||
$step2 = New-Object -TypeName UpgradePlan
|
||||
$step2.FullPath = "C:\mock-file.ps1"
|
||||
$step2.UpgradeType = [UpgradeStepType]::Cmdlet
|
||||
$step2.PlanResult = [PlanResultReasonCode]::WarningSplattedParameters
|
||||
$step2.PlanSeverity = [DiagnosticSeverity]::Warning
|
||||
$step2.Location = "mocked-file.ps1:20:1"
|
||||
$step2.Original = "Get-AzureRmCommandThatIsUsingSplattedParameters"
|
||||
$step2.Replacement = "Get-AzCommandThatIsUsingSplattedParameters" # has a replacement, but is in warning state.
|
||||
|
||||
$plan = @( $step1, $step2 )
|
||||
|
||||
Mock -CommandName Invoke-ModuleUpgradeStep -ModuleName Az.Tools.Migration -MockWith { } -Verifiable
|
||||
Mock -CommandName Get-Content -MockWith { return "mock-file-contents" } -Verifiable
|
||||
Mock -CommandName Set-Content -MockWith { }
|
||||
|
||||
# ensure we don't send telemetry during tests.
|
||||
Mock -CommandName Send-MetricsIfDataCollectionEnabled -ModuleName Az.Tools.Migration -MockWith { }
|
||||
|
||||
# act
|
||||
$results = Invoke-AzUpgradeModulePlan -Plan $plan -FileEditMode ModifyExistingFiles -Confirm:$false
|
||||
|
||||
# assert
|
||||
$results | Should Not Be $null
|
||||
$results.Count | Should Be 2
|
||||
|
||||
# first plan step should have upgraded fine.
|
||||
$results[0].GetType().FullName | Should Be 'UpgradeResult'
|
||||
$results[0].UpgradeResult.ToString() | Should Be 'UpgradeCompleted'
|
||||
$results[0].UpgradeSeverity.ToString() | Should Be 'Information'
|
||||
|
||||
# second plan step should be executed, but return a Completed w/ warnings state.
|
||||
$results[1].GetType().FullName | Should Be 'UpgradeResult'
|
||||
$results[1].UpgradeResult.ToString() | Should Be 'UpgradedWithWarnings'
|
||||
$results[1].UpgradeSeverity.ToString() | Should Be 'Warning'
|
||||
|
||||
Assert-VerifiableMock
|
||||
}
|
||||
It 'Should be able to handle file upgrade errors' {
|
||||
# arrange
|
||||
$step1 = New-Object -TypeName UpgradePlan
|
||||
|
|
|
@ -41,7 +41,6 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
|
||||
$cmdlet1Param = New-Object -TypeName CommandReferenceParameter
|
||||
$cmdlet1Param.Name = "EnvironmentName"
|
||||
$cmdlet1Param.Value = "mock-value"
|
||||
$cmdlet1Param.StartOffset = 27
|
||||
|
||||
$cmdlet1.Parameters.Add($cmdlet1Param)
|
||||
|
@ -234,34 +233,6 @@ InModuleScope -ModuleName Az.Tools.Migration -ScriptBlock {
|
|||
$results[8].Replacement | Should Be 'Login-AzAccount'
|
||||
$results[8].StartOffset | Should Be 33
|
||||
}
|
||||
It 'Should be able to generate warnings for splatted parameter scenarios' {
|
||||
# arrange
|
||||
$cmdlet1 = New-Object -TypeName CommandReference
|
||||
$cmdlet1.FileName = "mock-file.ps1"
|
||||
$cmdlet1.FullPath = "C:\mock-file.ps1"
|
||||
$cmdlet1.CommandName = "Login-AzureRmAccount"
|
||||
$cmdlet1.StartOffset = 10
|
||||
$cmdlet1.HasSplattedArguments = $true
|
||||
|
||||
$foundCmdlets = @()
|
||||
$foundCmdlets += $cmdlet1
|
||||
|
||||
# ensure we don't send telemetry during tests.
|
||||
Mock -CommandName Send-MetricsIfDataCollectionEnabled -ModuleName Az.Tools.Migration -MockWith { }
|
||||
|
||||
# act
|
||||
# should generate a warning, and an upgrade step
|
||||
$results = New-AzUpgradeModulePlan -AzureRmCmdReference $foundCmdlets -ToAzVersion 4.8.0
|
||||
|
||||
# assert
|
||||
$results | Should Not Be $null
|
||||
$results.Count | Should Be 1
|
||||
|
||||
$results.UpgradeType.ToString() | Should Be 'Cmdlet'
|
||||
$results.PlanResult.ToString() | Should Be "WarningSplattedParameters"
|
||||
$results.PlanSeverity.ToString() | Should Be 'Warning'
|
||||
$results.PlanResultReason.Contains("splatted parameters") | Should Be $true
|
||||
}
|
||||
It 'Should be able to generate errors for source cmdlets missing upgrade aliases' {
|
||||
# arrange
|
||||
$cmdlet1 = New-Object -TypeName CommandReference
|
||||
|
|
Загрузка…
Ссылка в новой задаче