Add LocationChangedAction handler and tests to support the Windows Compat module (#7552)

Add LocationChangedAction handler and tests to support the Windows Compat module.
This commit is contained in:
Bruce Payette
2018-08-22 12:08:03 -07:00
committed by Travis Plunk
parent 97d2e10c22
commit 4943bbfd9e
3 changed files with 93 additions and 0 deletions
@@ -356,6 +356,11 @@ namespace System.Management.Automation
/// </summary>
public System.EventHandler<CommandLookupEventArgs> PostCommandLookupAction { get; set; }
/// <summary>
/// Gets or sets the action that is invoked everytime the runspace location (cwd) is changed.
/// </summary>
public System.EventHandler<LocationChangedEventArgs> LocationChangedAction { get; set; }
/// <summary>
/// Returns the CmdletInfo object that corresponds to the name argument
/// </summary>
@@ -200,6 +200,7 @@ namespace System.Management.Automation
throw PSTraceSource.NewArgumentNullException("path");
}
PathInfo current = CurrentLocation;
string originalPath = path;
string driveName = null;
ProviderInfo provider = null;
@@ -553,6 +554,15 @@ namespace System.Management.Automation
// Set the $PWD variable to the new location
this.SetVariable(SpecialVariables.PWDVarPath, this.CurrentLocation, false, true, CommandOrigin.Internal);
// If an action has been defined for location changes, invoke it now.
if (PublicSessionState.InvokeCommand.LocationChangedAction != null)
{
var eventArgs = new LocationChangedEventArgs(PublicSessionState, current, CurrentLocation);
PublicSessionState.InvokeCommand.LocationChangedAction.Invoke(ExecutionContext.CurrentRunspace, eventArgs);
s_tracer.WriteLine("Invoked LocationChangedAction");
}
return this.CurrentLocation;
} // SetLocation
@@ -1046,5 +1056,47 @@ namespace System.Management.Automation
#endregion push-Pop current working directory
} // SessionStateInternal class
/// <summary>
/// Event argument for the LocationChangedAction containing
/// information about the old location we were in and the new
/// location we changed to.
/// </summary>
public class LocationChangedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the LocationChangedEventArgs class.
/// </summary>
/// <param name="sessionState">
/// The public session state instance associated with this runspace.
/// </param>
/// <param name="oldPath">
/// The path we changed locations from.
/// </param>
/// <param name="newPath">
/// The path we change locations to.
/// </param>
internal LocationChangedEventArgs(SessionState sessionState, PathInfo oldPath, PathInfo newPath)
{
SessionState = sessionState;
OldPath = oldPath;
NewPath = newPath;
}
/// <summary>
/// Gets the path we changed location from.
/// </summary>
public PathInfo OldPath { get; internal set; }
/// <summary>
/// Gets the path we changed location to.
/// </summary>
public PathInfo NewPath { get; internal set; }
/// <summary>
/// Gets the session state instance for the current runspace.
/// </summary>
public SessionState SessionState { get; internal set; }
}
}
@@ -144,4 +144,40 @@ Describe "Set-Location" -Tags "CI" {
{ Set-Location - } | Should -Throw -ErrorId 'System.InvalidOperationException,Microsoft.PowerShell.Commands.SetLocationCommand'
}
}
Context 'Test the LocationChangedAction event handler' {
AfterEach {
$ExecutionContext.InvokeCommand.LocationChangedAction = $null
}
It 'The LocationChangedAction should fire when changing location' {
$initialPath = $pwd
$oldPath = $null
$newPath = $null
$eventSessionState = $null
$eventRunspace = $null
$ExecutionContext.InvokeCommand.LocationChangedAction = {
(Get-Variable eventRunspace).Value = $this
(Get-Variable eventSessionState).Value = $_.SessionState
(Get-Variable oldPath).Value = $_.oldPath
(Get-Variable newPath).Value = $_.newPath
}
Set-Location ..
$newPath.Path | Should -Be $pwd.Path
$oldPath.Path | Should -Be $initialPath.Path
$eventSessionState | Should -Be $ExecutionContext.SessionState
$eventRunspace | Should -Be ([runspace]::DefaultRunspace)
}
It 'Errors in the LocationChangedAction should be catchable but not fail the cd' {
$location = $PWD
Set-Location ..
$ExecutionContext.InvokeCommand.LocationChangedAction = { throw "Boom" }
# Verify that the exception occurred
{ Set-Location $location } | Should Throw "Boom"
# But the location should still have changed
$PWD.Path | Should -Be $location.Path
}
}
}