diff --git a/CHANGELOG/preview.md b/CHANGELOG/preview.md index 779044fdb78..dc6f6acd1f3 100644 --- a/CHANGELOG/preview.md +++ b/CHANGELOG/preview.md @@ -14,7 +14,7 @@ - Update `ConciseView` to use `TargetObject` if applicable (#11075) - Fix `NullReferenceException` in `CompletionCompleters` public methods (#11274) - Fix apartment thread state check on non-Windows platforms (#11301) -- Update setting PSModulePath to concatenate the process and machine environment variables (#11276) +- Update setting `PSModulePath` to concatenate the process and machine environment variables (#11276) - Bump `.NET Core` to `3.1.0` (#11260) - Fix detection of `$PSHOME` in front of `$env:PATH` (#11141) @@ -27,8 +27,8 @@ - Update calculation of char width to respect `CJK` chars correctly (#11262) - Add `Unblock-File` for macOS (#11137) - Fix regression in `Get-PSCallStack` (#11210) (Thanks @iSazonov!) -- Remove autoloading of the `ScheduledJob` module when using Job cmdlets (#11194) -- Add `OutputType` to `Get-Error` cmdlet and preserve original typenames (#10856) +- Avoid automatically loading the `ScheduledJob` module when using Job cmdlets (#11194) +- Add `OutputType` to `Get-Error` cmdlet and preserve original `TypeNames` (#10856) - Fix null reference in `SupportsVirtualTerminal` property (#11105) ### Code Cleanup diff --git a/src/System.Management.Automation/engine/LanguagePrimitives.cs b/src/System.Management.Automation/engine/LanguagePrimitives.cs index c097ead06b9..500c4439cc9 100644 --- a/src/System.Management.Automation/engine/LanguagePrimitives.cs +++ b/src/System.Management.Automation/engine/LanguagePrimitives.cs @@ -593,7 +593,9 @@ public static PSDataCollection GetPSDataCollection(object inputValue) /// Object to compare first to. /// True if first is equal to the second. public static new bool Equals(object first, object second) - => Equals(first, second, false, CultureInfo.InvariantCulture); + { + return Equals(first, second, false, CultureInfo.InvariantCulture); + } /// /// Used to compare two objects for equality converting the second to the type of the first, if required. @@ -604,7 +606,9 @@ public static PSDataCollection GetPSDataCollection(object inputValue) /// to specify the type of string comparison /// True if first is equal to the second. public static bool Equals(object first, object second, bool ignoreCase) - => Equals(first, second, ignoreCase, CultureInfo.InvariantCulture); + { + return Equals(first, second, ignoreCase, CultureInfo.InvariantCulture); + } /// /// Used to compare two objects for equality converting the second to the type of the first, if required. @@ -642,28 +646,25 @@ public static bool Equals(object first, object second, bool ignoreCase, IFormatP if (first == null) { - return IsNullLike(second); + if (second == null) return true; + return false; } if (second == null) { - return IsNullLike(first); + return false; // first is not null } + string firstString = first as string; string secondString; - if (first is string firstString) + if (firstString != null) { secondString = second as string ?? (string)LanguagePrimitives.ConvertTo(second, typeof(string), culture); - return culture.CompareInfo.Compare( - firstString, - secondString, - ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0; + return (culture.CompareInfo.Compare(firstString, secondString, + ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0); } - if (first.Equals(second)) - { - return true; - } + if (first.Equals(second)) return true; Type firstType = first.GetType(); Type secondType = second.GetType(); @@ -707,24 +708,24 @@ public static bool Equals(object first, object second, bool ignoreCase, IFormatP /// Helper method for [Try]Compare to determine object ordering with null. /// /// The numeric value to compare to null. - /// True if the number to compare is on the right hand side in the comparison. + /// True if the number to compare is on the right hand side if the comparison. private static int CompareObjectToNull(object value, bool numberIsRightHandSide) { var i = numberIsRightHandSide ? -1 : 1; // If it's a positive number, including 0, it's greater than null // for everything else it's less than zero... - return value switch - { - Int16 i16 => Math.Sign(i16) < 0 ? -i : i, - Int32 i32 => Math.Sign(i32) < 0 ? -i : i, - Int64 i64 => Math.Sign(i64) < 0 ? -i : i, - sbyte s => Math.Sign(s) < 0 ? -i : i, - float f => Math.Sign(f) < 0 ? -i : i, - double d => Math.Sign(d) < 0 ? -i : i, - decimal m => Math.Sign(m) < 0 ? -i : i, - _ => IsNullLike(value) ? 0 : i - }; + switch (value) + { + case Int16 i16: return Math.Sign(i16) < 0 ? -i : i; + case Int32 i32: return Math.Sign(i32) < 0 ? -i : i; + case Int64 i64: return Math.Sign(i64) < 0 ? -i : i; + case sbyte sby: return Math.Sign(sby) < 0 ? -i : i; + case float f: return Math.Sign(f) < 0 ? -i : i; + case double d: return Math.Sign(d) < 0 ? -i : i; + case decimal de: return Math.Sign(de) < 0 ? -i : i; + default: return i; + } } /// @@ -740,7 +741,9 @@ private static int CompareObjectToNull(object value, bool numberIsRightHandSide) /// to the type of . /// public static int Compare(object first, object second) - => LanguagePrimitives.Compare(first, second, false, CultureInfo.InvariantCulture); + { + return LanguagePrimitives.Compare(first, second, false, CultureInfo.InvariantCulture); + } /// /// Compare first and second, converting second to the @@ -756,7 +759,9 @@ public static int Compare(object first, object second) /// to the type of . /// public static int Compare(object first, object second, bool ignoreCase) - => LanguagePrimitives.Compare(first, second, ignoreCase, CultureInfo.InvariantCulture); + { + return LanguagePrimitives.Compare(first, second, ignoreCase, CultureInfo.InvariantCulture); + } /// /// Compare first and second, converting second to the @@ -774,12 +779,15 @@ public static int Compare(object first, object second, bool ignoreCase) /// public static int Compare(object first, object second, bool ignoreCase, IFormatProvider formatProvider) { - formatProvider ??= CultureInfo.InvariantCulture; + if (formatProvider == null) + { + formatProvider = CultureInfo.InvariantCulture; + } var culture = formatProvider as CultureInfo; if (culture == null) { - throw PSTraceSource.NewArgumentException(nameof(formatProvider)); + throw PSTraceSource.NewArgumentException("formatProvider"); } first = PSObject.Base(first); @@ -787,7 +795,7 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP if (first == null) { - return CompareObjectToNull(second, true); + return second == null ? 0 : CompareObjectToNull(second, true); } if (second == null) @@ -797,7 +805,7 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP if (first is string firstString) { - var secondString = second as string; + string secondString = second as string; if (secondString == null) { try @@ -806,26 +814,19 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP } catch (PSInvalidCastException e) { - throw PSTraceSource.NewArgumentException( - nameof(second), - ExtendedTypeSystem.ComparisonFailure, - first.ToString(), - second.ToString(), - e.Message); + throw PSTraceSource.NewArgumentException("second", ExtendedTypeSystem.ComparisonFailure, + first.ToString(), second.ToString(), e.Message); } } - return culture.CompareInfo.Compare( - firstString, - secondString, - ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); + return culture.CompareInfo.Compare(firstString, secondString, + ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None); } Type firstType = first.GetType(); Type secondType = second.GetType(); int firstIndex = LanguagePrimitives.TypeTableIndex(firstType); int secondIndex = LanguagePrimitives.TypeTableIndex(secondType); - if ((firstIndex != -1) && (secondIndex != -1)) { return LanguagePrimitives.NumericCompare(first, second, firstIndex, secondIndex); @@ -838,12 +839,8 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP } catch (PSInvalidCastException e) { - throw PSTraceSource.NewArgumentException( - nameof(second), - ExtendedTypeSystem.ComparisonFailure, - first.ToString(), - second.ToString(), - e.Message); + throw PSTraceSource.NewArgumentException("second", ExtendedTypeSystem.ComparisonFailure, + first.ToString(), second.ToString(), e.Message); } if (first is IComparable firstComparable) @@ -858,7 +855,7 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP // At this point, we know that they aren't equal but we have no way of // knowing which should compare greater than the other so we throw an exception. - throw PSTraceSource.NewArgumentException(nameof(first), ExtendedTypeSystem.NotIcomparable, first.ToString()); + throw PSTraceSource.NewArgumentException("first", ExtendedTypeSystem.NotIcomparable, first.ToString()); } /// @@ -871,7 +868,9 @@ public static int Compare(object first, object second, bool ignoreCase, IFormatP /// zero if it is greater or zero if they are the same. /// True if the comparison was successful, false otherwise. public static bool TryCompare(object first, object second, out int result) - => TryCompare(first, second, ignoreCase: false, CultureInfo.InvariantCulture, out result); + { + return TryCompare(first, second, ignoreCase: false, CultureInfo.InvariantCulture, out result); + } /// /// Tries to compare first and second, converting second to the type of the first, if necessary. @@ -883,7 +882,9 @@ public static bool TryCompare(object first, object second, out int result) /// Less than zero if first is smaller than second, more than zero if it is greater or zero if they are the same. /// True if the comparison was successful, false otherwise. public static bool TryCompare(object first, object second, bool ignoreCase, out int result) - => TryCompare(first, second, ignoreCase, CultureInfo.InvariantCulture, out result); + { + return TryCompare(first, second, ignoreCase, CultureInfo.InvariantCulture, out result); + } /// /// Tries to compare first and second, converting second to the type of the first, if necessary. @@ -899,7 +900,10 @@ public static bool TryCompare(object first, object second, bool ignoreCase, out public static bool TryCompare(object first, object second, bool ignoreCase, IFormatProvider formatProvider, out int result) { result = 0; - formatProvider ??= CultureInfo.InvariantCulture; + if (formatProvider == null) + { + formatProvider = CultureInfo.InvariantCulture; + } if (!(formatProvider is CultureInfo culture)) { @@ -984,10 +988,8 @@ public static bool TryCompare(object first, object second, bool ignoreCase, IFor public static bool IsTrue(object obj) { // null is a valid argument - it converts to false... - if (IsNullLike(obj)) - { + if (obj == null || obj == AutomationNull.Value) return false; - } obj = PSObject.Base(obj); @@ -1013,7 +1015,8 @@ public static bool IsTrue(object obj) if (objType == typeof(SwitchParameter)) return ((SwitchParameter)obj).ToBool(); - if (obj is IList objectArray) + IList objectArray = obj as IList; + if (objectArray != null) { return IsTrue(objectArray); } @@ -1058,20 +1061,15 @@ internal static bool IsTrue(IList objectArray) } } - /// - /// Internal routine that determines if an object meets any of our criteria for true null. - /// - /// The object to test. - /// True if the object is null. - public static bool IsNull(object obj) => obj == null || obj == AutomationNull.Value; - /// /// Internal routine that determines if an object meets any of our criteria for null. - /// This method additionally checks for and /// /// The object to test. /// True if the object is null. - public static bool IsNullLike(object obj) => IsNull(obj) || obj == DBNull.Value || obj == NullString.Value; + internal static bool IsNull(object obj) + { + return (obj == null || obj == AutomationNull.Value); + } /// /// Auxiliary for the cases where we want a new PSObject or null. @@ -3086,17 +3084,15 @@ private static object ConvertToVoid(object valueToConvert, return AutomationNull.Value; } - private static bool ConvertClassToBool( - object valueToConvert, - Type resultType, - bool recursion, - PSObject originalValueToConvert, - IFormatProvider formatProvider, - TypeTable backupTable) + private static bool ConvertClassToBool(object valueToConvert, + Type resultType, + bool recursion, + PSObject originalValueToConvert, + IFormatProvider formatProvider, + TypeTable backupTable) { typeConversion.WriteLine("Converting ref to boolean."); - // Both NullString and DBNull should be treated the same as true nulls for the purposes of this conversion. - return !IsNullLike(valueToConvert); + return valueToConvert != null; } private static bool ConvertValueToBool(object valueToConvert, @@ -4712,11 +4708,10 @@ internal static IConversionData FigureConversion(object valueToConvert, Type res { PSObject valueAsPsObj; Type originalType; - - if (IsNull(valueToConvert)) + if (valueToConvert == null || valueToConvert == AutomationNull.Value) { - originalType = typeof(Null); valueAsPsObj = null; + originalType = typeof(Null); } else { diff --git a/src/System.Management.Automation/engine/parser/Compiler.cs b/src/System.Management.Automation/engine/parser/Compiler.cs index cfc1e8727d0..6b64b2260bd 100644 --- a/src/System.Management.Automation/engine/parser/Compiler.cs +++ b/src/System.Management.Automation/engine/parser/Compiler.cs @@ -280,8 +280,8 @@ internal static class CachedReflectionInfo internal static readonly MethodInfo LanguagePrimitives_GetInvalidCastMessages = typeof(LanguagePrimitives).GetMethod(nameof(LanguagePrimitives.GetInvalidCastMessages), StaticFlags); - internal static readonly MethodInfo LanguagePrimitives_IsNullLike = - typeof(LanguagePrimitives).GetMethod(nameof(LanguagePrimitives.IsNullLike), StaticPublicFlags); + internal static readonly MethodInfo LanguagePrimitives_IsNull = + typeof(LanguagePrimitives).GetMethod(nameof(LanguagePrimitives.IsNull), StaticFlags); internal static readonly MethodInfo LanguagePrimitives_ThrowInvalidCastException = typeof(LanguagePrimitives).GetMethod(nameof(LanguagePrimitives.ThrowInvalidCastException), StaticFlags); @@ -982,7 +982,7 @@ private static Expression Coalesce(Expression left, Expression right) { return left; } - else if(leftType == typeof(DBNull) || leftType == typeof(NullString) || leftType == typeof(AutomationNull)) + else if(leftType == typeof(AutomationNull)) { return right; } @@ -992,7 +992,7 @@ private static Expression Coalesce(Expression left, Expression right) Expression rhs = right.Cast(typeof(object)); return Expression.Condition( - Expression.Call(CachedReflectionInfo.LanguagePrimitives_IsNullLike, lhs), + Expression.Call(CachedReflectionInfo.LanguagePrimitives_IsNull, lhs), rhs, lhs); } @@ -6547,7 +6547,7 @@ public object VisitIndexExpression(IndexExpressionAst indexExpressionAst) private static Expression GetNullConditionalWrappedExpression(Expression targetExpr, Expression memberAccessExpression) { return Expression.Condition( - Expression.Call(CachedReflectionInfo.LanguagePrimitives_IsNullLike, targetExpr.Cast(typeof(object))), + Expression.Call(CachedReflectionInfo.LanguagePrimitives_IsNull, targetExpr.Cast(typeof(object))), ExpressionCache.NullConstant, memberAccessExpression); } diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index af0a196bd7d..3aaf877e882 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -3028,9 +3028,7 @@ private DynamicMetaObject CompareEQ(DynamicMetaObject target, if (target.Value == null) { return new DynamicMetaObject( - LanguagePrimitives.IsNullLike(arg.Value) - ? ExpressionCache.BoxedTrue - : ExpressionCache.BoxedFalse, + arg.Value == null ? ExpressionCache.BoxedTrue : ExpressionCache.BoxedFalse, target.CombineRestrictions(arg)); } @@ -3038,9 +3036,7 @@ private DynamicMetaObject CompareEQ(DynamicMetaObject target, if (enumerable == null && arg.Value == null) { return new DynamicMetaObject( - LanguagePrimitives.IsNullLike(target.Value) - ? ExpressionCache.BoxedTrue - : ExpressionCache.BoxedFalse, + ExpressionCache.BoxedFalse, target.CombineRestrictions(arg)); } @@ -3055,19 +3051,14 @@ private DynamicMetaObject CompareNE(DynamicMetaObject target, if (target.Value == null) { return new DynamicMetaObject( - LanguagePrimitives.IsNullLike(arg.Value) - ? ExpressionCache.BoxedFalse - : ExpressionCache.BoxedTrue, + arg.Value == null ? ExpressionCache.BoxedFalse : ExpressionCache.BoxedTrue, target.CombineRestrictions(arg)); } var enumerable = PSEnumerableBinder.IsEnumerable(target); if (enumerable == null && arg.Value == null) { - return new DynamicMetaObject( - LanguagePrimitives.IsNullLike(target.Value) - ? ExpressionCache.BoxedFalse - : ExpressionCache.BoxedTrue, + return new DynamicMetaObject(ExpressionCache.BoxedTrue, target.CombineRestrictions(arg)); } diff --git a/test/powershell/Host/Startup.Tests.ps1 b/test/powershell/Host/Startup.Tests.ps1 index 6fb2b7336ac..0436d67819f 100644 --- a/test/powershell/Host/Startup.Tests.ps1 +++ b/test/powershell/Host/Startup.Tests.ps1 @@ -26,7 +26,6 @@ Describe "Validate start of console host" -Tag CI { 'System.Diagnostics.Debug.dll' 'System.Diagnostics.FileVersionInfo.dll' 'System.Diagnostics.Process.dll' - 'System.Diagnostics.TraceSource.dll' 'System.Diagnostics.Tracing.dll' 'System.IO.FileSystem.AccessControl.dll' 'System.IO.FileSystem.dll' @@ -54,7 +53,6 @@ Describe "Validate start of console host" -Tag CI { 'System.Runtime.Loader.dll' 'System.Runtime.Numerics.dll' 'System.Runtime.Serialization.Formatters.dll' - 'System.Runtime.Serialization.Primitives.dll' 'System.Security.AccessControl.dll' 'System.Security.Cryptography.Encoding.dll' 'System.Security.Cryptography.X509Certificates.dll' @@ -78,6 +76,8 @@ Describe "Validate start of console host" -Tag CI { 'System.Security.Cryptography.Primitives.dll' 'System.Security.Principal.dll' 'System.Threading.Overlapped.dll' + 'System.Diagnostics.TraceSource.dll' + 'System.Runtime.Serialization.Primitives.dll' ) } else { diff --git a/test/powershell/Language/Operators/NullConditional.Tests.ps1 b/test/powershell/Language/Operators/NullConditional.Tests.ps1 index 3bb2140271d..90db13decba 100644 --- a/test/powershell/Language/Operators/NullConditional.Tests.ps1 +++ b/test/powershell/Language/Operators/NullConditional.Tests.ps1 @@ -62,7 +62,7 @@ Describe 'NullCoalesceOperations' -Tags 'CI' { It 'Lhs is DBNull' { $x = [System.DBNull]::Value $x ??= 200 - $x | Should -Be 200 + $x | Should -Be ([System.DBNull]::Value) } It 'Lhs is AutomationNull' { @@ -74,7 +74,7 @@ Describe 'NullCoalesceOperations' -Tags 'CI' { It 'Lhs is NullString' { $x = [NullString]::Value $x ??= 200 - $x | Should -Be 200 + $x | Should -Be ([NullString]::Value) } It 'Lhs is empty string' { @@ -146,7 +146,7 @@ Describe 'NullCoalesceOperations' -Tags 'CI' { It 'Lhs is DBNull' { $x = [System.DBNull]::Value - $x ?? 200 | Should -Be 200 + $x ?? 200 | Should -Be ([System.DBNull]::Value) } It 'Lhs is AutomationNull' { @@ -156,21 +156,17 @@ Describe 'NullCoalesceOperations' -Tags 'CI' { It 'Lhs is NullString' { $x = [NullString]::Value - $x ?? 200 | Should -Be 200 + $x ?? 200 | Should -Be ([NullString]::Value) } It 'Rhs is a get variable expression' { - $x = [System.DBNull]::Value + $x = $null $y = 2 $x ?? $y | Should -Be 2 } It 'Lhs is a constant' { - [System.DBNull]::Value ?? 2 | Should -Be 2 - } - - It 'Both are null constants' { - [System.DBNull]::Value ?? [NullString]::Value | Should -Be ([NullString]::Value) + [System.DBNull]::Value ?? 2 | Should -Be ([System.DBNull]::Value) } It 'Lhs is $?' { diff --git a/test/powershell/Language/Scripting/NullRepresentatives.Tests.ps1 b/test/powershell/Language/Scripting/NullRepresentatives.Tests.ps1 deleted file mode 100644 index 4c1863bb653..00000000000 --- a/test/powershell/Language/Scripting/NullRepresentatives.Tests.ps1 +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. - -using namespace System.Management.Automation.Internal - -Describe 'Null Representatives' -Tags 'CI' { - - Context 'Comparisons with $null' { - BeforeAll { - $TestValues = @( - @{ Value = { [AutomationNull]::Value } } - @{ Value = { [DBNull]::Value } } - @{ Value = { [NullString]::Value } } - ) - } - - It ' should be equivalent to $null (RHS: $null)' -TestCases $TestValues { - param($Value) - - $Value.InvokeReturnAsIs() -eq $null | Should -BeTrue - } - - It '$null should be equivalent to (LHS: $null)' -TestCases $TestValues { - param($Value) - - $null -eq $Value.InvokeReturnAsIs() | Should -BeTrue - } - } - - Context 'Comparisons with other null representatives' { - <# - The only unequal null-representatives are NullString and DBNull. - AutomationNull and $null are always considered equal already, so therefore NullString compares as - true with both of them, as does DBNull. - - However, as NullString and DBNull have different purposes, it makes more sense to consider them unequal - when directly compared with each other. - #> - It 'DBNull should not be equal to NullString' { - [DBNull]::Value -eq [NullString]::Value | Should -BeFalse - [NullString]::Value -eq [DBNull]::Value | Should -BeFalse - } - } - - Context 'Casting Behaviour' { - BeforeAll { - $TestValues = @( - @{ Value = { $null } } - @{ Value = { [DBNull]::Value } } - @{ Value = { [NullString]::Value } } - @{ Value = { [AutomationNull]::Value } } - ) - } - - It ' should cast to $false' -TestCases $TestValues { - param($Value) - - [bool]($Value.InvokeReturnAsIs()) | Should -BeFalse - } - - It '-not should be $true' -TestCases $TestValues { - param($Value) - - -not $Value.InvokeReturnAsIs() | Should -BeTrue - } - - It ' should be treated as $false by Where-Object' -TestCases $TestValues { - param($Value) - - 100 | Where-Object { $Value.InvokeReturnAsIs() } | Should -BeNullOrEmpty - } - } - - Context 'Collection Comparisons' { - BeforeAll { - $NullArray = $null, $null, [DBNull]::Value, $null, $null, [NullString]::Value - } - - It ' should correctly filter the array and return results' { - param($Value, $ExpectedCount) - - $NullArray -eq $Value | Should -HaveCount $ExpectedCount - } -TestCases @( - @{ Value = $null; ExpectedCount = 6 } - @{ Value = [DBNull]::Value; ExpectedCount = 5 } - @{ Value = [NullString]::Value; ExpectedCount = 5 } - ) - } -} diff --git a/test/powershell/engine/Basic/SemanticVersion.Tests.ps1 b/test/powershell/engine/Basic/SemanticVersion.Tests.ps1 index 606b4a82715..65b6136b257 100644 --- a/test/powershell/engine/Basic/SemanticVersion.Tests.ps1 +++ b/test/powershell/engine/Basic/SemanticVersion.Tests.ps1 @@ -109,8 +109,8 @@ Describe "SemanticVersion api tests" -Tags 'CI' { @{ lhs = $v1_0_0_alpha; rhs = $v1_0_0_alpha2 } @{ lhs = $v1_0_0_alpha; rhs = $v1_0_0 } @{ lhs = $v1_0_0_beta; rhs = $v1_0_0 } - @{ lhs = $v2_1_0; rhs = "3.0" } - @{ lhs = "1.5"; rhs = $v2_1_0 } + @{ lhs = $v2_1_0; rhs = "3.0"} + @{ lhs = "1.5"; rhs = $v2_1_0} ) } @@ -176,39 +176,38 @@ Describe "SemanticVersion api tests" -Tags 'CI' { Context "Error handling" { It ": ''" -TestCases @( - @{ name = "Missing parts: 'null'"; errorId = "PSArgumentNullException"; expectedResult = $false; version = $null } - @{ name = "Missing parts: 'NullString'"; errorId = "PSArgumentNullException"; expectedResult = $false; version = [NullString]::Value } - @{ name = "Missing parts: 'EmptyString'"; errorId = "FormatException"; expectedResult = $false; version = "" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "-" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "." } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "+" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "-alpha" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1..0" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.-alpha" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.+alpha" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0-alpha+" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0-+" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0+-" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0+" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0-" } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0." } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0." } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.." } - @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = ".0.0" } - @{ name = "Range check of versions"; errorId = "FormatException"; expectedResult = $false; version = "-1.0.0" } - @{ name = "Range check of versions"; errorId = "FormatException"; expectedResult = $false; version = "1.-1.0" } - @{ name = "Range check of versions"; errorId = "FormatException"; expectedResult = $false; version = "1.0.-1" } - @{ name = "Format errors"; errorId = "FormatException"; expectedResult = $false; version = "aa.0.0" } - @{ name = "Format errors"; errorId = "FormatException"; expectedResult = $false; version = "1.bb.0" } - @{ name = "Format errors"; errorId = "FormatException"; expectedResult = $false; version = "1.0.cc" } + @{ name = "Missing parts: 'null'"; errorId = "PSArgumentNullException";expectedResult = $false; version = $null } + @{ name = "Missing parts: 'NullString'"; errorId = "PSArgumentNullException";expectedResult = $false; version = [NullString]::Value } + @{ name = "Missing parts: 'EmptyString'";errorId = "FormatException"; expectedResult = $false; version = "" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "-" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "." } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "+" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "-alpha" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1..0" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.-alpha" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.+alpha" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0-alpha+" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0-+" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0+-" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0+" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0-" } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.0." } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0." } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = "1.0.." } + @{ name = "Missing parts"; errorId = "FormatException"; expectedResult = $false; version = ".0.0" } + @{ name = "Range check of versions"; errorId = "FormatException"; expectedResult = $false; version = "-1.0.0" } + @{ name = "Range check of versions"; errorId = "FormatException"; expectedResult = $false; version = "1.-1.0" } + @{ name = "Range check of versions"; errorId = "FormatException"; expectedResult = $false; version = "1.0.-1" } + @{ name = "Format errors"; errorId = "FormatException"; expectedResult = $false; version = "aa.0.0" } + @{ name = "Format errors"; errorId = "FormatException"; expectedResult = $false; version = "1.bb.0" } + @{ name = "Format errors"; errorId = "FormatException"; expectedResult = $false; version = "1.0.cc" } ) { param($version, $expectedResult, $errorId) { [SemanticVersion]::new($version) } | Should -Throw -ErrorId $errorId - if ([LanguagePrimitives]::IsNull($version)) { + if ($version -eq $null) { # PowerShell convert $null to Empty string { [SemanticVersion]::Parse($version) } | Should -Throw -ErrorId "FormatException" - } - else { + } else { { [SemanticVersion]::Parse($version) } | Should -Throw -ErrorId $errorId } $semVer = $null diff --git a/test/powershell/engine/ETS/TypeTable.Tests.ps1 b/test/powershell/engine/ETS/TypeTable.Tests.ps1 index 789c5c0e290..dbeb75be11f 100644 --- a/test/powershell/engine/ETS/TypeTable.Tests.ps1 +++ b/test/powershell/engine/ETS/TypeTable.Tests.ps1 @@ -19,7 +19,14 @@ Describe "Built-in type information tests" -Tag "CI" { It "Should have correct number of built-in type items in type table" { $isUnixStatEnabled = $EnabledExperimentalFeatures -contains 'PSUnixFileStat' - $types.Count | Should -BeExactly ($isUnixStatEnabled ? 272 : 273) + $expected = if ($IsWindows) { + 273 + } elseif ($isUnixStatEnabled) { + 272 + } else { + 271 + } + $types.Count | Should -BeExactly $expected } It "Should have expected member info for 'System.Diagnostics.ProcessModule'" {