diff --git a/.gitignore b/.gitignore
index c8259cf33..9cdda77f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
bin/
obj/
+debug/
project.lock.json
*-tests.xml
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 59b831f29..afd0d5d0b 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -7,8 +7,8 @@
"request": "launch",
"justMyCode": false,
"stopAtEntry": true,
- "program": "${workspaceRoot}/bin/powershell",
- "args": [ ],
+ "program": "${workspaceRoot}/debug/powershell",
+ "args": [ "-NonInteractive" ],
"preLaunchTask": "build",
"cwd": "${workspaceRoot}"
},
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 9864ad2b4..3c853f8aa 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -8,7 +8,7 @@
"tasks": [
{
"taskName": "build",
- "args": [ "Import-Module ${workspaceRoot}/PowerShellGitHubDev.psm1; Start-PSBuild" ],
+ "args": [ "Import-Module ${workspaceRoot}/PowerShellGitHubDev.psm1; Start-PSBuild -Output debug" ],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
diff --git a/PowerShellGitHubDev.psm1 b/PowerShellGitHubDev.psm1
index 3dde4e746..3a5bee497 100644
--- a/PowerShellGitHubDev.psm1
+++ b/PowerShellGitHubDev.psm1
@@ -25,6 +25,7 @@ function Start-PSBuild {
param(
[switch]$NoPath,
[switch]$Restore,
+ [string]$Output,
[Parameter(ParameterSetName='CoreCLR')]
[switch]$Publish,
@@ -105,7 +106,7 @@ function Start-PSBuild {
}
# set output options
- $OptionsArguments = @{Publish=$Publish; FullCLR=$FullCLR; Runtime=$Runtime}
+ $OptionsArguments = @{Publish=$Publish; Output=$Output; FullCLR=$FullCLR; Runtime=$Runtime}
$script:Options = New-PSOptions @OptionsArguments
# setup arguments
@@ -115,6 +116,9 @@ function Start-PSBuild {
} else {
$Arguments += "build"
}
+ if ($Output) {
+ $Arguments += "--output", (Join-Path $PSScriptRoot $Output)
+ }
$Arguments += "--configuration", $Options.Configuration
$Arguments += "--framework", $Options.Framework
$Arguments += "--runtime", $Options.Runtime
@@ -212,6 +216,7 @@ function New-PSOptions {
[string]$Runtime,
[switch]$Publish,
+ [string]$Output,
[switch]$FullCLR
)
@@ -261,21 +266,25 @@ function New-PSOptions {
"powershell.exe"
}
- # Build the Output path in script scope
- $Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework)
+ # Build the Output path
+ if ($Output) {
+ $Output = Join-Path $PSScriptRoot $Output
+ } else {
+ $Output = [IO.Path]::Combine($Top, "bin", $Configuration, $Framework)
- # FullCLR only builds a library, so there is no runtime component
- if (-not $FullCLR) {
- $Output = [IO.Path]::Combine($Output, $Runtime)
+ # FullCLR only builds a library, so there is no runtime component
+ if (-not $FullCLR) {
+ $Output = [IO.Path]::Combine($Output, $Runtime)
+ }
+
+ # Publish injects the publish directory
+ if ($Publish) {
+ $Output = [IO.Path]::Combine($Output, "publish")
+ }
+
+ $Output = [IO.Path]::Combine($Output, $Executable)
}
- # Publish injects the publish directory
- if ($Publish) {
- $Output = [IO.Path]::Combine($Output, "publish")
- }
-
- $Output = [IO.Path]::Combine($Output, $Executable)
-
return @{ Top = $Top;
Configuration = $Configuration;
Framework = $Framework;
@@ -388,7 +397,7 @@ function Start-PSBootstrap {
} elseif ($IsWindows -And -Not $IsCore) {
Remove-Item -ErrorAction SilentlyContinue -Recurse -Force ~\AppData\Local\Microsoft\dotnet
Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1
- ./install.ps1
+ ./install.ps1 -Version 1.0.0-rc2-002655
} else {
Write-Warning "Start-PSBootstrap cannot be run in Core PowerShell on Windows (need Invoke-WebRequest!)"
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 14dd8eac4..e07381a57 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -43,6 +43,20 @@ more information.
[error]: https://blogs.msdn.microsoft.com/kebab/2013/06/09/an-introduction-to-error-handling-in-powershell/
+I just pulled master, why did my build fail?
+============================================
+
+There are two likely reasons:
+
+If the `src/windows-build` submodule was changed, you need to manually run `git
+submodule update` to check your sources out to the correct commits. Pulling does
+not automatically do this. When a submodule is out-of-date, you will likely be
+missing required build files.
+
+If package dependencies were changed in any `project.json`, you need to manually
+run `dotnet restore` to update your local dependency graphs. `Start-PSBuild
+-Restore` can automatically do this.
+
Why did `Start-PSBuild` tell me to update `dotnet`?
===================================================
diff --git a/docs/debugging/README.md b/docs/debugging/README.md
index 2994048d1..319c423d6 100644
--- a/docs/debugging/README.md
+++ b/docs/debugging/README.md
@@ -2,7 +2,7 @@ Debugging
=========
VS Code
--------
+=======
[Experimental .NET Core Debugging in VS Code][core-debug] enables
cross-platform debugging with the [Visual Studio Code][vscode] editor.
@@ -38,19 +38,32 @@ process named `powershell`, and will attach to it. If you need more
fine grained control, replace `processName` with `processId` and
provide a PID. (Please be careful not to commit such a change).
+Important Note
+--------------
+
+Debugging is very sensitive to the versions of our .NET Core packages, VS Code,
+and the C# extension.
+
+- Use the VS Code [Insiders][] build
+- Use the latest pre-release of the [C# extension][]
+- Refer to the pre-release [documentation][]
+
[core-debug]: https://blogs.msdn.microsoft.com/visualstudioalm/2016/03/10/experimental-net-core-debugging-in-vs-code/
[vscode]: https://code.visualstudio.com/
[OmniSharp]: https://github.com/OmniSharp/omnisharp-vscode
[vscclrdebugger]: http://aka.ms/vscclrdebugger
+[insiders]: https://code.visualstudio.com/insiders
+[C# extension]: https://github.com/OmniSharp/omnisharp-vscode/releases
+[documentation]: https://github.com/OmniSharp/omnisharp-vscode/pull/157
corehost
---------
+========
The native executable prouduced by .NET CLI will produce trace output
if launched with `COREHOST_TRACE=1 ./powershell`.
CoreCLR PAL
------------
+===========
The native code in the CLR has debug channels to selectively output
information to the console. These are controlled by the
diff --git a/src/Microsoft.Management.Infrastructure/project.json b/src/Microsoft.Management.Infrastructure/project.json
index c30907ee6..e6ff6d089 100644
--- a/src/Microsoft.Management.Infrastructure/project.json
+++ b/src/Microsoft.Management.Infrastructure/project.json
@@ -8,7 +8,7 @@
},
"dependencies": {
- "Microsoft.Management.Infrastructure.Native": "1.0.0-rc3"
+ "Microsoft.Management.Infrastructure.Native": "1.0.0-rc4"
},
"frameworks": {
diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs
index d2ba941ee..fb58250d3 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Navigation.cs
@@ -3562,7 +3562,22 @@ namespace Microsoft.PowerShell.Commands
}
bool shouldRecurse = Recurse;
- if (!Recurse && hasChildren)
+ bool treatAsFile = false;
+ try
+ {
+ System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(providerPath);
+ if (!Platform.IsWindows && di != null && (di.Attributes & System.IO.FileAttributes.ReparsePoint) != 0)
+ {
+ shouldRecurse = false;
+ treatAsFile = true;
+ }
+ }
+ catch (System.IO.FileNotFoundException)
+ {
+ // not a directory
+ }
+
+ if (!treatAsFile && !Recurse && hasChildren)
{
// Get the localized prompt string
diff --git a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs
index d66748dfa..dfd9c13fb 100644
--- a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs
+++ b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs
@@ -1070,17 +1070,6 @@ namespace System.Management.Automation
}
}
- internal static string WinGetMachineName()
- {
- // In future release of operating systems, you might be able to rename a machine without
- // rebooting. Therefore, don't cache this machine name.
- StringBuilder buf = new StringBuilder(MaxMachineNameLength);
- int len = MaxMachineNameLength;
- if (Win32Native.GetComputerName(buf, ref len) == 0)
- throw new InvalidOperationException(CoreClrStubResources.CannotGetComputerName);
- return buf.ToString();
- }
-
///
/// MachineName
///
@@ -1088,14 +1077,7 @@ namespace System.Management.Automation
{
get
{
- if (Platform.IsWindows)
- {
- return WinGetMachineName();
- }
- else
- {
- return Platform.NonWindowsGetMachineName();
- }
+ return System.Environment.MachineName;
}
}
@@ -1276,9 +1258,6 @@ namespace System.Management.Automation
// Win32 return type is BOOLEAN (which is 1 byte and not BOOL which is 4bytes)
internal static extern byte GetUserNameEx(int format, [Out] StringBuilder domainName, ref uint domainNameLen);
- [DllImport("api-ms-win-downlevel-kernel32-l2-1-0.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal extern static int GetComputerName([Out]StringBuilder nameBuffer, ref int bufferSize);
-
[DllImport("api-ms-win-core-localization-l1-2-1.dll", CharSet = CharSet.Unicode)]
internal static extern int FormatMessage(int dwFlags, IntPtr lpSource, int dwMessageId,
int dwLanguageId, [Out]StringBuilder lpBuffer,
diff --git a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs
index 50c651425..34623fc1b 100644
--- a/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs
+++ b/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs
@@ -351,18 +351,6 @@ namespace System.Management.Automation
}
}
- internal static string NonWindowsGetMachineName()
- {
- if (!IsWindows)
- {
- return LinuxPlatform.HostName;
- }
- else
- {
- throw new PlatformNotSupportedException();
- }
- }
-
// Hostname in this context seems to be the FQDN
internal static string NonWindowsGetHostName()
{
@@ -470,22 +458,6 @@ namespace System.Management.Automation
internal static class LinuxPlatform
{
- public static string HostName
- {
- get
- {
- StringBuilder value = new StringBuilder(1024);
- uint valueLen = (uint)value.Capacity;
- string computerName = Native.GetComputerName();
- if (string.IsNullOrEmpty(computerName))
- {
- int lastError = Marshal.GetLastWin32Error();
- throw new InvalidOperationException("LinuxPlatform.HostName error: " + lastError);
- }
- return computerName;
- }
- }
-
private static string _userName;
public static string UserName
{
@@ -696,10 +668,6 @@ namespace System.Management.Automation
[return: MarshalAs(UnmanagedType.LPStr)]
internal static extern string GetUserName();
- [DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.LPStr)]
- internal static extern string GetComputerName();
-
[DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int GetLinkCount([MarshalAs(UnmanagedType.LPStr)]string filePath, out int linkCount);
diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs
index 79e92e995..6dc033623 100644
--- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs
+++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs
@@ -2858,7 +2858,7 @@ namespace Microsoft.PowerShell.Commands
}
//if this is a reparse point and force is not specified then warn user but dont remove the directory.
- if (((directory.Attributes & FileAttributes.ReparsePoint) != 0) && !Force)
+ if (Platform.IsWindows && ((directory.Attributes & FileAttributes.ReparsePoint) != 0) && !Force)
{
String error = StringUtil.Format(FileSystemProviderStrings.DirectoryReparsePoint, directory.FullName);
Exception e = new IOException(error);
@@ -8452,10 +8452,24 @@ namespace Microsoft.PowerShell.Commands
IntPtr dangerousHandle = handle.DangerousGetHandle();
int bytesReturned;
+ // Do a FSCTL_GET_REPARSE_POINT first because the ReparseTag could be
+ // IO_REPARSE_TAG_MOUNT_POINT or IO_REPARSE_TAG_SYMLINK.
+ // Using the wrong one results in mismatched-tag error.
+
REPARSE_GUID_DATA_BUFFER junctionData = new REPARSE_GUID_DATA_BUFFER();
+ ClrFacade.StructureToPtr(junctionData, outBuffer, false);
+
+ result = DeviceIoControl(dangerousHandle, FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0,
+ outBuffer, inOutBufferSize, out bytesReturned, IntPtr.Zero);
+ if (!result)
+ {
+ int lastError = Marshal.GetLastWin32Error();
+ throw new Win32Exception(lastError);
+ }
+
+ junctionData = ClrFacade.PtrToStructure(outBuffer);
junctionData.ReparseDataLength = 0;
junctionData.DataBuffer = new char[MAX_REPARSE_SIZE];
- junctionData.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
ClrFacade.StructureToPtr(junctionData, inBuffer, false);
diff --git a/src/windows-build b/src/windows-build
index 674541f74..7144b55bd 160000
--- a/src/windows-build
+++ b/src/windows-build
@@ -1 +1 @@
-Subproject commit 674541f7444de5be5f8c63e3a2ef2d98739c1943
+Subproject commit 7144b55bdafb71dc91af4f5fb13b6e14904b789f
diff --git a/test/csharp/test_CorePsPlatform.cs b/test/csharp/test_CorePsPlatform.cs
index a99c3b0f9..1284b2583 100644
--- a/test/csharp/test_CorePsPlatform.cs
+++ b/test/csharp/test_CorePsPlatform.cs
@@ -99,7 +99,7 @@ namespace PSTests
// The process should return an exit code of 0 on success
Assert.Equal(0, process.ExitCode);
// It should be the same as what our platform code returns
- Assert.Equal(hostname, Platform.NonWindowsGetMachineName());
+ Assert.Equal(hostname, System.Management.Automation.Environment.MachineName);
}
}
diff --git a/test/powershell/ConvertFrom-StringData.Tests.ps1 b/test/powershell/ConvertFrom-StringData.Tests.ps1
index f1ec128e6..fe1f6232a 100644
--- a/test/powershell/ConvertFrom-StringData.Tests.ps1
+++ b/test/powershell/ConvertFrom-StringData.Tests.ps1
@@ -1,3 +1,23 @@
+Describe "ConvertFrom-StringData DRT Unit Tests" -Tags DRT {
+ It "Should able to throw error when convert invalid line" {
+ $str =@"
+#comments here
+abc
+#comments here
+def=content of def
+"@
+ try
+ {
+ ConvertFrom-StringData $str
+ Throw "we expect 'InvalidOperation' exception"
+ }
+ catch
+ {
+ $_.FullyQualifiedErrorId | Should be "InvalidOperation,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand"
+ }
+ }
+}
+
Describe "ConvertFrom-StringData" {
$sampleData = @'
foo = 0
diff --git a/test/powershell/Format-Custom.Tests.ps1 b/test/powershell/Format-Custom.Tests.ps1
index 3486a1428..df7d1144c 100644
--- a/test/powershell/Format-Custom.Tests.ps1
+++ b/test/powershell/Format-Custom.Tests.ps1
@@ -23,3 +23,22 @@ Describe "Format-Custom" {
}
}
+
+
+Describe "Format-Custom DRT basic functionality" -Tags DRT{
+ It "Format-Custom with subobject should work"{
+ $expectResult1 = "this is the name"
+ $expectResult2 = "this is the name of the sub object"
+ $testObject = @{}
+ $testObject.name = $expectResult1
+ $testObject.subObjectValue = @{}
+ $testObject.subObjectValue.name = $expectResult2
+ $testObject.subObjectValue.array = (0..63)
+ $testObject.subObjectValue.stringarray = @("one","two")
+ $result = $testObject | Format-Custom | Out-String
+ $result | Should Match $expectResult1
+ $result | Should Match $expectResult2
+ $result | Should Match "one"
+ $result | Should Match "two"
+ }
+}
\ No newline at end of file
diff --git a/test/powershell/Format-List.Tests.ps1 b/test/powershell/Format-List.Tests.ps1
index 7e8e67f57..782456551 100644
--- a/test/powershell/Format-List.Tests.ps1
+++ b/test/powershell/Format-List.Tests.ps1
@@ -32,27 +32,27 @@ Describe "Format-List" {
It "Should be able to call a property of the piped input" {
# Tested on two input commands to verify functionality.
- { Get-Command | Format-List -Property Name } | Should Not BeNullOrEmpty
+ { Get-Command | Select-Object -First 5 | Format-List -Property Name } | Should Not BeNullOrEmpty
{ Get-Date | Format-List -Property DisplayName } | Should Not BeNullOrEmpty
}
It "Should be able to display a list of props when separated by a comma" {
- (Get-Command | Format-List -Property Name,Source | Out-String) -Split "${nl}" |
+ (Get-Command | Select-Object -First 5 | Format-List -Property Name,Source | Out-String) -Split "${nl}" |
Where-Object { $_.trim() -ne "" } |
ForEach-Object { $_ | Should Match "(Name)|(Source)" }
}
It "Should show the requested prop in every element" {
# Testing each element of format-list, using a for-each loop since the Format-List is so opaque
- (Get-Command | Format-List -Property Source | Out-String) -Split "${nl}" |
+ (Get-Command | Select-Object -First 5 | Format-List -Property Source | Out-String) -Split "${nl}" |
Where-Object { $_.trim() -ne "" } |
ForEach-Object { $_ | Should Match "Source :" }
}
It "Should not show anything other than the requested props" {
- $output = Get-Command | Format-List -Property Name | Out-String
+ $output = Get-Command | Select-Object -First 5 | Format-List -Property Name | Out-String
$output | Should Not Match "CommandType :"
$output | Should Not Match "Source :"
@@ -66,3 +66,62 @@ Describe "Format-List" {
}
}
+
+Describe "Format-List DRT basic functionality" -Tags DRT{
+ It "Format-List with array should work"{
+ $al = (0..255)
+ $info = @{}
+ $info.array = $al
+ $result = $info | Format-List | Out-String
+ $result | Should Match "Name : array\s+Value : {0, 1, 2, 3...}"
+ }
+
+ It "Format-List with No Objects for End-To-End should work"{
+ $p = @{}
+ $result = $p | Format-List -Force -Property "foo","bar" | Out-String
+ $result.Trim() | Should BeNullOrEmpty
+ }
+
+ It "Format-List with Null Objects for End-To-End should work"{
+ $p = $null
+ $result = $p | Format-List -Force -Property "foo","bar" | Out-String
+ $result.Trim() | Should BeNullOrEmpty
+ }
+
+ It "Format-List with single line string for End-To-End should work"{
+ $p = "single line string"
+ $result = $p | Format-List -Force -Property "foo","bar" | Out-String
+ $result.Trim() | Should BeNullOrEmpty
+ }
+
+ It "Format-List with multiple line string for End-To-End should work"{
+ $p = "Line1\nLine2"
+ $result = $p | Format-List -Force -Property "foo","bar" | Out-String
+ $result.Trim() | Should BeNullOrEmpty
+ }
+
+ It "Format-List with string sequence for End-To-End should work"{
+ $p = "Line1","Line2"
+ $result = $p | Format-List -Force -Property "foo","bar" | Out-String
+ $result.Trim() | Should BeNullOrEmpty
+ }
+
+ It "Format-List with complex object for End-To-End should work"{
+ Add-Type -TypeDefinition "public enum MyDayOfWeek{Sun,Mon,Tue,Wed,Thr,Fri,Sat}"
+ $eto = New-Object MyDayOfWeek
+ $info = @{}
+ $info.intArray = 1,2,3,4
+ $info.arrayList = "string1","string2"
+ $info.enumerable = [MyDayOfWeek]$eto
+ $info.enumerableTestObject = $eto
+ $result = $info|Format-List|Out-String
+ $result | Should Match "Name : enumerableTestObject"
+ $result | Should Match "Value : Sun"
+ $result | Should Match "Name : arrayList"
+ $result | Should Match "Value : {string1, string2}"
+ $result | Should Match "Name : enumerable"
+ $result | Should Match "Value : Sun"
+ $result | Should Match "Name : intArray"
+ $result | Should Match "Value : {1, 2, 3, 4}"
+ }
+}
diff --git a/test/powershell/Format-Wide.Tests.ps1 b/test/powershell/Format-Wide.Tests.ps1
index e4b35780b..c4e9a5862 100644
--- a/test/powershell/Format-Wide.Tests.ps1
+++ b/test/powershell/Format-Wide.Tests.ps1
@@ -8,26 +8,90 @@ Describe "Format-Wide" {
}
It "Should be able to specify the columns in output using the column switch" {
- { ls | Format-Wide -Column 3 } | Should Not Throw
+ { Get-ChildItem | Format-Wide -Column 3 } | Should Not Throw
}
It "Should be able to use the autosize switch" {
- { ls | Format-Wide -Autosize } | Should Not Throw
+ { Get-ChildItem | Format-Wide -Autosize } | Should Not Throw
}
It "Should be able to take inputobject instead of pipe" {
- { Format-Wide -InputObject $(ls) } | Should Not Throw
+ { Format-Wide -InputObject $(Get-ChildItem) } | Should Not Throw
}
It "Should be able to use the property switch" {
- { Format-Wide -InputObject $(ls) -Property Mode } | Should Not Throw
+ { Format-Wide -InputObject $(Get-ChildItem) -Property Mode } | Should Not Throw
}
It "Should throw an error when property switch and view switch are used together" {
- { Format-Wide -InputObject $(ls) -Property CreationTime -View aoeu } | Should Throw "Found invalid data"
+ try
+ {
+ Format-Wide -InputObject $(Get-ChildItem) -Property CreationTime -View aoeu
+ }
+ catch
+ {
+ $_.FullyQualifiedErrorId | Should be "FormatCannotSpecifyViewAndProperty,Microsoft.PowerShell.Commands.FormatWideCommand"
+ }
}
It "Should throw and suggest proper input when view is used with invalid input without the property switch" {
- { Format-Wide -InputObject $(gps) -View aoeu } | Should Throw
+ { Format-Wide -InputObject $(Get-Process) -View aoeu } | Should Throw
}
}
+
+Describe "Format-Wide DRT basic functionality" -Tags DRT{
+ It "Format-Wide with array should work"{
+ $al = (0..255)
+ $info = @{}
+ $info.array = $al
+ $result = $info | Format-Wide | Out-String
+ $result | Should Match "array"
+ }
+
+ It "Format-Wide with No Objects for End-To-End should work"{
+ $p = @{}
+ $result = $p | Format-Wide | Out-String
+ $result | Should BeNullOrEmpty
+ }
+
+ It "Format-Wide with Null Objects for End-To-End should work"{
+ $p = $null
+ $result = $p | Format-Wide | Out-String
+ $result | Should BeNullOrEmpty
+ }
+
+ It "Format-Wide with single line string for End-To-End should work"{
+ $p = "single line string"
+ $result = $p | Format-Wide | Out-String
+ $result | Should Match $p
+ }
+
+ It "Format-Wide with multiple line string for End-To-End should work"{
+ $p = "Line1\nLine2"
+ $result = $p | Format-Wide | Out-String
+ $result | Should Match "Line1"
+ $result | Should Match "Line2"
+ }
+
+ It "Format-Wide with string sequence for End-To-End should work"{
+ $p = "Line1","Line2"
+ $result = $p |Format-Wide | Out-String
+ $result | Should Match "Line1"
+ $result | Should Match "Line2"
+ }
+
+ It "Format-Wide with complex object for End-To-End should work"{
+ Add-Type -TypeDefinition "public enum MyDayOfWeek{Sun,Mon,Tue,Wed,Thr,Fri,Sat}"
+ $eto = New-Object MyDayOfWeek
+ $info = @{}
+ $info.intArray = 1,2,3,4
+ $info.arrayList = "string1","string2"
+ $info.enumerable = [MyDayOfWeek]$eto
+ $info.enumerableTestObject = $eto
+ $result = $info|Format-Wide|Out-String
+ $result | Should Match "intArray"
+ $result | Should Match "arrayList"
+ $result | Should Match "enumerable"
+ $result | Should Match "enumerableTestObject"
+ }
+}
\ No newline at end of file
diff --git a/test/powershell/Get-Random.Tests.ps1 b/test/powershell/Get-Random.Tests.ps1
index 0d769846e..58cca7cb9 100644
--- a/test/powershell/Get-Random.Tests.ps1
+++ b/test/powershell/Get-Random.Tests.ps1
@@ -1,3 +1,94 @@
+Describe "Get-Random DRT Unit Tests" -Tags DRT{
+ $testData = @(
+ @{ Name = 'no params'; Maximum = $null; Minimum = $null; GreaterThan = -1; LessThan = ([int32]::MaxValue); Type = 'System.Int32' }
+ @{ Name = 'only positive maximum number'; Maximum = 100; Minimum = $null; GreaterThan = -1; LessThan = 100; Type = 'System.Int32' }
+ @{ Name = 'maximum set to 0, Minimum to a negative number'; Maximum = 0; Minimum = -100; GreaterThan = -101; LessThan = 0; Type = 'System.Int32' }
+ @{ Name = 'positive maximum, negative Minimum'; Maximum = 100; Minimum = -100; GreaterThan = -101; LessThan = 100; Type = 'System.Int32' }
+ @{ Name = 'both negative'; Maximum = -100; Minimum = -200; GreaterThan = -201; LessThan = -100; Type = 'System.Int32' }
+ @{ Name = 'both negative with parentheses'; Maximum = (-100); Minimum = (-200); GreaterThan = -201; LessThan = -100; Type = 'System.Int32' }
+ @{ Name = 'maximum enclosed in quote'; Maximum = '8'; Minimum = 5; GreaterThan = 4; LessThan = 8; Type = 'System.Int32' }
+ @{ Name = 'minimum enclosed in quote'; Maximum = 8; Minimum = '5'; GreaterThan = 4; LessThan = 8; Type = 'System.Int32' }
+ @{ Name = 'maximum with plus sign'; Maximum = +100; Minimum = 0; GreaterThan = -1; LessThan = 100; Type = 'System.Int32' }
+ @{ Name = 'maximum with plus sign and quote'; Maximum = '+100'; Minimum = 0; GreaterThan = -1; LessThan = 100; Type = 'System.Int32' }
+ @{ Name = 'both with quote'; Maximum = '+100'; Minimum = '-100'; GreaterThan = -101; LessThan = 100; Type = 'System.Int32' }
+ @{ Name = 'maximum set to kb'; Maximum = '1kb'; Minimum = 0; GreaterThan = -1; LessThan = 1024; Type = 'System.Int32' }
+ @{ Name = 'maximum is Int64.MaxValue'; Maximum = ([int64]::MaxValue); Minimum = $null; GreaterThan = ([int64]-1); LessThan = ([int64]::MaxValue); Type = 'System.Int64' }
+ @{ Name = 'maximum is a 64-bit integer'; Maximum = ([int64]100); Minimum = $null; GreaterThan = ([int64]-1); LessThan = ([int64]100); Type = 'System.Int64' }
+ @{ Name = 'maximum set to a large integer greater than int32.MaxValue'; Maximum = 100000000000; Minimum = $null; GreaterThan = ([int64]-1); LessThan = ([int64]100000000000); Type = 'System.Int64' }
+ @{ Name = 'maximum set to 0, Minumum set to a negative 64-bit integer'; Maximum = ([int64]0); Minimum = ([int64]-100); GreaterThan = ([int64]-101); LessThan = ([int64]0); Type = 'System.Int64' }
+ @{ Name = 'maximum set to positive 64-bit number, min set to negative 64-bit number'; Maximum = ([int64]100); Minimum = ([int64]-100); GreaterThan = ([int64]-101); LessThan = ([int64]100); Type = 'System.Int64' }
+ @{ Name = 'both are negative 64-bit number'; Maximum = ([int64]-100); Minimum = ([int64]-200); GreaterThan = ([int64]-201); LessThan = ([int64]-100); Type = 'System.Int64' }
+ @{ Name = 'both are negative 64-bit number with parentheses'; Maximum = ([int64](-100)); Minimum = ([int64](-200)); GreaterThan = ([int64]-201); LessThan = ([int64]-100); Type = 'System.Int64' }
+ @{ Name = 'max is 32-bit, min is 64-bit integer'; Maximum = '8'; Minimum = ([int64]5); GreaterThan = ([int64]4); LessThan = ([int64]8); Type = 'System.Int64' }
+ @{ Name = 'max is 64-bit, min is 32-bit integer'; Maximum = ([int64]8); Minimum = '5'; GreaterThan = ([int64]4); LessThan = ([int64]8); Type = 'System.Int64' }
+ @{ Name = 'max set to a 32-bit integer, min set to [int64]0'; Maximum = +100; Minimum = ([int64]0); GreaterThan = ([int64]-1); LessThan = ([int64]100); Type = 'System.Int64' }
+ @{ Name = 'max set to a 32-bit integer with quote'; Maximum = '+100'; Minimum = ([int64]0); GreaterThan = ([int64]-1); LessThan = ([int64]100); Type = 'System.Int64' }
+ @{ Name = 'max is [int64]0, min is a 32-bit integer'; Maximum = ([int64]0); Minimum = '-100'; GreaterThan = ([int64]-101); LessThan = ([int64]0); Type = 'System.Int64' }
+ @{ Name = 'min set to 1MB, max set to a 64-bit integer greater than min'; Maximum = ([int64]1048585); Minimum = '1mb'; GreaterThan = ([int64]1048575); LessThan = ([int64]1048585); Type = 'System.Int64' }
+ @{ Name = 'max set to 1tb, min set to 10 mb'; Maximum = '1tb'; Minimum = '10mb'; GreaterThan = ([int64]10485759); LessThan = ([int64]1099511627776); Type = 'System.Int64' }
+ @{ Name = 'max is int64.MaxValue, min is Int64.MinValue'; Maximum = ([int64]::MaxValue); Minimum = ([int64]::MinValue); GreaterThan = ([int64]::MinValue); LessThan = ([int64]::MaxValue); Type = 'System.Int64' }
+ @{ Name = 'both are int64.MaxValue plus a 32-bit integer'; Maximum = ([int64](([int]::MaxValue)+15)); Minimum = ([int64](([int]::MaxValue)+10)); GreaterThan = ([int64](([int]::MaxValue)+9)); LessThan = ([int64](([int]::MaxValue)+15)); Type = 'System.Int64' }
+ @{ Name = 'both are greater than int32.MaxValue without specified type, and max with quote'; Maximum = '100099000001'; Minimum = 100000000001; GreaterThan = ([int64]10000000000); LessThan = ([int64]100099000001); Type = 'System.Int64' }
+ @{ Name = 'both are greater than int32.MaxValue without specified type, and min with quote'; Maximum = 100000002230; Minimum = '100000002222'; GreaterThan = ([int64]100000002221); LessThan = ([int64]100000002230); Type = 'System.Int64' }
+ @{ Name = 'max is greater than int32.MaxValue without specified type'; Maximum = 90000000000; Minimum = 4; GreaterThan = ([int64]3); LessThan = ([int64]90000000000); Type = 'System.Int64' }
+ @{ Name = 'max is a double-precision number'; Maximum = 100.0; Minimum = $null; GreaterThan = -1.0; LessThan = 100.0; Type = 'System.Double' }
+ @{ Name = 'both are double-precision numbers, min is negative.'; Maximum = 0.0; Minimum = -100.0; GreaterThan = -101.0; LessThan = 0.0; Type = 'System.Double' }
+ @{ Name = 'both are double-precision number, max is positive, min is negative.'; Maximum = 100.0; Minimum = -100.0; GreaterThan = -101.0; LessThan = 100.0; Type = 'System.Double' }
+ @{ Name = 'max is a double-precision number, min is int32'; Maximum = 8.0; Minimum = 5; GreaterThan = 4.0; LessThan = 8.0; Type = 'System.Double' }
+ @{ Name = 'min is a double-precision number, max is int32'; Maximum = 8; Minimum = 5.0; GreaterThan = 4.0; LessThan = 8.0; Type = 'System.Double' }
+ @{ Name = 'max set to a special double number'; Maximum = 20.; Minimum = 0.0; GreaterThan = -1.0; LessThan = 20.0; Type = 'System.Double' }
+ @{ Name = 'max is double with quote'; Maximum = '20.'; Minimum = 0.0; GreaterThan = -1.0; LessThan = 20.0; Type = 'System.Double' }
+ @{ Name = 'max is double with plus sign'; Maximum = +100.0; Minimum = 0; GreaterThan = -1.0; LessThan = 100.0; Type = 'System.Double' }
+ @{ Name = 'max is doulbe with plus sign and enclosed in quote'; Maximum = '+100.0'; Minimum = 0; GreaterThan = -1.0; LessThan = 100.0; Type = 'System.Double' }
+ @{ Name = 'both set to the special numbers as 1.0e+xx '; Maximum = $null; Minimum = 1.0e+100; GreaterThan = 1.0e+99; LessThan = ([double]::MaxValue); Type = 'System.Double' }
+ @{ Name = 'max is Double.MaxValue, min is Double.MinValue'; Maximum = ([double]::MaxValue); Minimum = ([double]::MinValue); GreaterThan = ([double]::MinValue); LessThan = ([double]::MaxValue); Type = 'System.Double' }
+
+ )
+
+ $testDataForError = @(
+ @{ Name = 'Min is greater than max and all are positive 32-bit integer'; Maximum = 10; Minimum = 20}
+ @{ Name = 'Min and Max are same and all are positive 32-bit integer'; Maximum = 20; Minimum = 20}
+ @{ Name = 'Min is greater than max and all are negative 32-bit integer'; Maximum = -20; Minimum = -10}
+ @{ Name = 'Min and Max are same and all are negative 32-bit integer'; Maximum = -20; Minimum = -20}
+ @{ Name = 'Min is greater than max and all are positive double-precision number'; Maximum = 10.0; Minimum = 20.0}
+ @{ Name = 'Min and Max are same and all are positive double-precision number'; Maximum = 20.0; Minimum = 20.0}
+ @{ Name = 'Min is greater than max and all are negative double-precision number'; Maximum = -20.0; Minimum = -10.0}
+ @{ Name = 'Min and Max are same and all are negative double-precision number'; Maximum = -20.0; Minimum = -20.0}
+ @{ Name = 'Max is a negative number, min is the default number '; Maximum = -10; Minimum = $null}
+
+ )
+
+ # minimum is always set to the actual low end of the range, details refer to closed issue #887.
+ It "get a correct random number for ''" -TestCases $testData {
+ param($maximum, $minimum, $greaterThan, $lessThan, $type)
+
+ $result = Get-Random -Maximum $maximum -Minimum $minimum
+ $result | Should BeGreaterThan $greaterThan
+ $result | Should BeLessThan $lessThan
+ $result.GetType().FullName | Should Be $type
+
+ }
+
+ It "Should be able to throw error when ''" -TestCases $testDataForError {
+ param($maximum, $minimum)
+ try
+ {
+ Get-Random -Minimum $minimum -Maximum $maximum
+ throw "OK"
+ }
+ catch
+ {
+ $_.FullyQualifiedErrorId | Should Be "MinGreaterThanOrEqualMax,Microsoft.PowerShell.Commands.GetRandomCommand"
+ }
+ }
+
+ It "Tests for setting the seed" {
+ $result1 = (get-random -SetSeed 123), (get-random)
+ $result2 = (get-random -SetSeed 123), (get-random)
+ $result1 | Should Be $result2
+ }
+}
+
Describe "Get-Random" {
It "Should return a random number greater than -1 " {
Get-Random | Should BeGreaterThan -1
diff --git a/test/powershell/Get-Unique.Tests.ps1 b/test/powershell/Get-Unique.Tests.ps1
index 8eade4134..2b5688e90 100644
--- a/test/powershell/Get-Unique.Tests.ps1
+++ b/test/powershell/Get-Unique.Tests.ps1
@@ -1,3 +1,22 @@
+Describe "Get-Unique DRT Unit Tests" -Tags DRT{
+ It "Command get-unique works with AsString switch" {
+ $inputArray = "aa","aa","Aa","ba","BA","BA"
+ $results = $inputArray | Get-Unique -AsString
+
+ $results.Length | Should Be 4
+
+ $results[0] | Should Be "aa"
+ $results[1] | Should Be "Aa"
+ $results[2] | Should Be "ba"
+ $results[3] | Should Be "BA"
+
+ $results[0].GetType().FullName | Should be System.String
+ $results[1].GetType().FullName | Should be System.String
+ $results[2].GetType().FullName | Should be System.String
+ $results[3].GetType().FullName | Should be System.String
+ }
+}
+
Describe "Get-Unique" {
$sortedList1 = 1,2,2,3,3,4,5
It "Should be able to use the Get-Unique cmdlet without error with inputObject switch" {
@@ -59,12 +78,12 @@ Describe "Get-Unique" {
$collection = "a", "b", "b", "d"
$expectedOutput = "a", "b", "d"
- $actual = Get-Unique -InputObject $collection
+ $actual = $collection | Get-Unique
- $actual.Length | Should Be $collection.Length
+ $actual.Length | Should Be $expectedOutput.Length
- $actual[0] | Should Be $collection[0]
- $actual[1] | Should Be $collection[1]
- $actual[2] | Should Be $collection[2]
+ $actual[0] | Should Be $expectedOutput[0]
+ $actual[1] | Should Be $expectedOutput[1]
+ $actual[2] | Should Be $expectedOutput[2]
}
}