diff --git a/src/CommunityToolkit.Maui.Core/Extensions/ColorConversionExtensions.shared.cs b/src/CommunityToolkit.Maui.Core/Extensions/ColorConversionExtensions.shared.cs index 7005dab0bf..80bbf975ef 100644 --- a/src/CommunityToolkit.Maui.Core/Extensions/ColorConversionExtensions.shared.cs +++ b/src/CommunityToolkit.Maui.Core/Extensions/ColorConversionExtensions.shared.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System.ComponentModel; +using System.Globalization; namespace CommunityToolkit.Maui.Core.Extensions; @@ -19,7 +20,7 @@ public static class ColorConversionExtensions public static string ToRgbString(this Color color) { ArgumentNullException.ThrowIfNull(color); - return $"RGB({color.GetByteRed()},{color.GetByteGreen()},{color.GetByteBlue()})"; + return FormattableString.Invariant($"RGB({color.GetByteRed()},{color.GetByteGreen()},{color.GetByteBlue()})"); } /// @@ -32,10 +33,24 @@ public static string ToRgbString(this Color color) /// and alpha is a value between 0 and 1. (e.g. RGBA(255,0,0,1) for ). /// /// Thrown when is null. - public static string ToRgbaString(this Color color, CultureInfo? cultureInfo = null) + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Do not use CultureInfo, this method should be culture invariant.")] + public static string ToRgbaString(this Color color, CultureInfo? cultureInfo) => ToRgbaString(color); + + + /// + /// Converts this to a containing the red, green, blue and alpha components. + /// + /// The to convert. + /// + /// A in the format: RGBA(red,green,blue,alpha) where red, green and blue will be a value between 0 and 255, + /// and alpha is a value between 0 and 1. (e.g. RGBA(255,0,0,1) for ). + /// + /// Thrown when is null. + public static string ToRgbaString(this Color color) { ArgumentNullException.ThrowIfNull(color); - return $"RGBA({color.GetByteRed()},{color.GetByteGreen()},{color.GetByteBlue()},{color.Alpha.ToString(cultureInfo)})"; + return FormattableString.Invariant($"RGBA({color.GetByteRed()},{color.GetByteGreen()},{color.GetByteBlue()},{color.Alpha})"); } /// @@ -50,7 +65,7 @@ public static string ToRgbaString(this Color color, CultureInfo? cultureInfo = n public static string ToCmykString(this Color color) { ArgumentNullException.ThrowIfNull(color); - return $"CMYK({color.GetPercentCyan():P0},{color.GetPercentMagenta():P0},{color.GetPercentYellow():P0},{color.GetPercentBlackKey():P0})"; + return FormattableString.Invariant($"CMYK({color.GetPercentCyan():0%},{color.GetPercentMagenta():0%},{color.GetPercentYellow():0%},{color.GetPercentBlackKey():0%})"); } /// @@ -63,10 +78,24 @@ public static string ToCmykString(this Color color) /// 0% and 100% and alpha will be a value between 0 and 1. (e.g. CMYKA(100%,100%,0%,100%,1) for ). /// /// Thrown when is null. - public static string ToCmykaString(this Color color, CultureInfo? cultureInfo = null) + + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Do not use CultureInfo, this method should be culture invariant.")] + public static string ToCmykaString(this Color color, CultureInfo? cultureInfo) => ToCmykaString(color); + + /// + /// Converts this to a containing the cyan, magenta, yellow, key and alpha components. + /// + /// The to convert. + /// + /// A in the format: CMYKA(cyan,magenta,yellow,key,alpha) where cyan, magenta, yellow and key will be a value between + /// 0% and 100% and alpha will be a value between 0 and 1. (e.g. CMYKA(100%,100%,0%,100%,1) for ). + /// + /// Thrown when is null. + public static string ToCmykaString(this Color color) { ArgumentNullException.ThrowIfNull(color); - return $"CMYKA({color.GetPercentCyan():P0},{color.GetPercentMagenta():P0},{color.GetPercentYellow():P0},{color.GetPercentBlackKey():P0},{color.Alpha.ToString(cultureInfo)})"; + return FormattableString.Invariant($"CMYKA({color.GetPercentCyan():0%},{color.GetPercentMagenta():0%},{color.GetPercentYellow():0%},{color.GetPercentBlackKey():0%},{color.Alpha})"); } /// @@ -81,7 +110,7 @@ public static string ToCmykaString(this Color color, CultureInfo? cultureInfo = public static string ToHslString(this Color color) { ArgumentNullException.ThrowIfNull(color); - return $"HSL({color.GetDegreeHue():0},{color.GetSaturation():P0},{color.GetLuminosity():P0})"; + return FormattableString.Invariant($"HSL({color.GetDegreeHue():0},{color.GetSaturation():0%},{color.GetLuminosity():0%})"); } /// @@ -94,10 +123,23 @@ public static string ToHslString(this Color color) /// will be a value between 0% and 100%, and alpha will be a value between 0 and 1. (e.g. HSLA(0,100%,50%,1) for ). /// /// Thrown when is null. - public static string ToHslaString(this Color color, CultureInfo? cultureInfo = null) + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Do not use CultureInfo, this method should be culture invariant.")] + public static string ToHslaString(this Color color, CultureInfo? cultureInfo) => ToHslaString(color); + + /// + /// Converts this to a containing the hue, saturation, lightness and alpha components. + /// + /// The to convert. + /// + /// A in the format: HSLA(hue,saturation,lightness,alpha) where hue will be a value between 0 and 360, saturation and lightness + /// will be a value between 0% and 100%, and alpha will be a value between 0 and 1. (e.g. HSLA(0,100%,50%,1) for ). + /// + /// Thrown when is null. + public static string ToHslaString(this Color color) { ArgumentNullException.ThrowIfNull(color); - return $"HSLA({color.GetDegreeHue():0},{color.GetSaturation():P0},{color.GetLuminosity():P0},{color.Alpha.ToString(cultureInfo)})"; + return FormattableString.Invariant($"HSLA({color.GetDegreeHue():0},{color.GetSaturation():0%},{color.GetLuminosity():0%},{color.Alpha})"); } /// diff --git a/src/CommunityToolkit.Maui.UnitTests/Behaviors/ValidationBehaviorTests.cs b/src/CommunityToolkit.Maui.UnitTests/Behaviors/ValidationBehaviorTests.cs index 834e3dbb1a..0882e97780 100644 --- a/src/CommunityToolkit.Maui.UnitTests/Behaviors/ValidationBehaviorTests.cs +++ b/src/CommunityToolkit.Maui.UnitTests/Behaviors/ValidationBehaviorTests.cs @@ -1,4 +1,5 @@ -using CommunityToolkit.Maui.Behaviors; +using System.Threading.Tasks; +using CommunityToolkit.Maui.Behaviors; using CommunityToolkit.Maui.UnitTests.Mocks; using Xunit; using Xunit.v3; @@ -8,7 +9,7 @@ namespace CommunityToolkit.Maui.UnitTests.Behaviors; public class ValidationBehaviorTests(ITestOutputHelper testOutputHelper) : BaseBehaviorTest(new MockValidationBehavior(), new View()) { [Fact] - public void ValidateOnValueChanged() + public async Task ValidateOnValueChanged() { // Arrange var entry = new Entry @@ -18,6 +19,7 @@ public void ValidateOnValueChanged() var behavior = new MockValidationBehavior() { ExpectedValue = "321", + SimulateValidationDelay = false, Flags = ValidationFlags.ValidateOnValueChanged }; @@ -26,6 +28,9 @@ public void ValidateOnValueChanged() // Act entry.Text = "321"; + // Fails sometimes randomly without delay + await Task.Delay(10, TestContext.Current.CancellationToken); + // Assert Assert.True(behavior.IsValid); } diff --git a/src/CommunityToolkit.Maui.UnitTests/Converters/ColorToCmykStringConverterTests.cs b/src/CommunityToolkit.Maui.UnitTests/Converters/ColorToCmykStringConverterTests.cs index 0e42a110db..7d0e58295d 100644 --- a/src/CommunityToolkit.Maui.UnitTests/Converters/ColorToCmykStringConverterTests.cs +++ b/src/CommunityToolkit.Maui.UnitTests/Converters/ColorToCmykStringConverterTests.cs @@ -135,15 +135,15 @@ public class ColorToCmykStringConverterTests : BaseOneWayConverterTest