|
9 | 9 | using System.Runtime.InteropServices;
|
10 | 10 | using System.Runtime.Versioning;
|
11 | 11 | using System.Text;
|
| 12 | +using System.Threading; |
12 | 13 | using System.Xml;
|
13 | 14 | using Microsoft.Build.BackEnd;
|
14 | 15 | using Microsoft.Build.Collections;
|
@@ -4893,5 +4894,100 @@ public void ExpandItemVectorFunctions_Exists_Directories()
|
4893 | 4894 | squiggleItems.Select(i => i.EvaluatedInclude).ShouldBe(new[] { alphaBetaPath, alphaDeltaPath }, Case.Insensitive);
|
4894 | 4895 | }
|
4895 | 4896 | }
|
| 4897 | + |
| 4898 | + [Fact] |
| 4899 | + public void ExpandItem_ConvertToStringUsingInvariantCultureForNumberData() |
| 4900 | + { |
| 4901 | + var currentThread = Thread.CurrentThread; |
| 4902 | + var originalCulture = currentThread.CurrentCulture; |
| 4903 | + var originalUICulture = currentThread.CurrentUICulture; |
| 4904 | + |
| 4905 | + try |
| 4906 | + { |
| 4907 | + var svSECultureInfo = new CultureInfo("sv-SE"); |
| 4908 | + using (var env = TestEnvironment.Create()) |
| 4909 | + { |
| 4910 | + currentThread.CurrentCulture = svSECultureInfo; |
| 4911 | + currentThread.CurrentUICulture = svSECultureInfo; |
| 4912 | + var root = env.CreateFolder(); |
| 4913 | + |
| 4914 | + var projectFile = env.CreateFile(root, ".proj", |
| 4915 | + @"<Project> |
| 4916 | +
|
| 4917 | + <PropertyGroup> |
| 4918 | + <_value>$([MSBuild]::Subtract(0, 1))</_value> |
| 4919 | + <_otherValue Condition=""'$(_value)' >= -1"">test-value</_otherValue> |
| 4920 | + </PropertyGroup> |
| 4921 | + <Target Name=""Build"" /> |
| 4922 | +</Project>"); |
| 4923 | + ProjectInstance projectInstance = new ProjectInstance(projectFile.Path); |
| 4924 | + projectInstance.GetPropertyValue("_value").ShouldBe("-1"); |
| 4925 | + projectInstance.GetPropertyValue("_otherValue").ShouldBe("test-value"); |
| 4926 | + } |
| 4927 | + } |
| 4928 | + finally |
| 4929 | + { |
| 4930 | + currentThread.CurrentCulture = originalCulture; |
| 4931 | + currentThread.CurrentUICulture = originalUICulture; |
| 4932 | + } |
| 4933 | + } |
| 4934 | + |
| 4935 | + [Fact] |
| 4936 | + public void ExpandItem_ConvertToStringUsingInvariantCultureForNumberData_RespectingChangeWave() |
| 4937 | + { |
| 4938 | + // Note: Skipping the test since it is not a valid scenario when ICU mode is not used. |
| 4939 | + if (!ICUModeAvailable()) |
| 4940 | + { |
| 4941 | + return; |
| 4942 | + } |
| 4943 | + |
| 4944 | + var currentThread = Thread.CurrentThread; |
| 4945 | + var originalCulture = currentThread.CurrentCulture; |
| 4946 | + var originalUICulture = currentThread.CurrentUICulture; |
| 4947 | + |
| 4948 | + try |
| 4949 | + { |
| 4950 | + var svSECultureInfo = new CultureInfo("sv-SE"); |
| 4951 | + using (var env = TestEnvironment.Create()) |
| 4952 | + { |
| 4953 | + env.SetEnvironmentVariable("MSBUILDDISABLEFEATURESFROMVERSION", ChangeWaves.Wave17_10.ToString()); |
| 4954 | + currentThread.CurrentCulture = svSECultureInfo; |
| 4955 | + currentThread.CurrentUICulture = svSECultureInfo; |
| 4956 | + var root = env.CreateFolder(); |
| 4957 | + |
| 4958 | + var projectFile = env.CreateFile(root, ".proj", |
| 4959 | + @"<Project> |
| 4960 | +
|
| 4961 | + <PropertyGroup> |
| 4962 | + <_value>$([MSBuild]::Subtract(0, 1))</_value> |
| 4963 | + <_otherValue Condition=""'$(_value)' >= -1"">test-value</_otherValue> |
| 4964 | + </PropertyGroup> |
| 4965 | + <Target Name=""Build"" /> |
| 4966 | +</Project>"); |
| 4967 | + var exception = Should.Throw<InvalidProjectFileException>(() => |
| 4968 | + { |
| 4969 | + new ProjectInstance(projectFile.Path); |
| 4970 | + }); |
| 4971 | + exception.BaseMessage.ShouldContain("A numeric comparison was attempted on \"$(_value)\""); |
| 4972 | + } |
| 4973 | + } |
| 4974 | + finally |
| 4975 | + { |
| 4976 | + currentThread.CurrentCulture = originalCulture; |
| 4977 | + currentThread.CurrentUICulture = originalUICulture; |
| 4978 | + } |
| 4979 | + } |
| 4980 | + |
| 4981 | + /// <summary> |
| 4982 | + /// Determines if ICU mode is enabled. |
| 4983 | + /// Copied from: https://learn.microsoft.com/en-us/dotnet/core/extensions/globalization-icu#determine-if-your-app-is-using-icu |
| 4984 | + /// </summary> |
| 4985 | + private static bool ICUModeAvailable() |
| 4986 | + { |
| 4987 | + SortVersion sortVersion = CultureInfo.InvariantCulture.CompareInfo.Version; |
| 4988 | + byte[] bytes = sortVersion.SortId.ToByteArray(); |
| 4989 | + int version = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0]; |
| 4990 | + return version != 0 && version == sortVersion.FullVersion; |
| 4991 | + } |
4896 | 4992 | }
|
4897 | 4993 | }
|
0 commit comments