Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 17f9241

Browse files
dansiegelAndreiMisiukevichTheCodeTravelerpictos
authored
allow TextCaseConverter to handle any value type (#1053)
* allow TextCaseConverter to handle any value type * remove duplicate Convert method * fix nullability * update TextCaseConverter tests * Update src/CommunityToolkit/Xamarin.CommunityToolkit/Converters/TextCaseConverter.shared.cs Co-authored-by: Andrei <[email protected]> Co-authored-by: Brandon Minnick <[email protected]> Co-authored-by: Pedro Jesus <[email protected]>
1 parent 72f6623 commit 17f9241

File tree

5 files changed

+73
-31
lines changed

5 files changed

+73
-31
lines changed
Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Globalization;
34
using Xamarin.CommunityToolkit.Converters;
5+
using Xamarin.CommunityToolkit.UnitTests.Mocks;
46
using Xunit;
57

68
namespace Xamarin.CommunityToolkit.UnitTests.Converters
@@ -10,35 +12,50 @@ public class TextCaseConverter_Tests
1012
const string test = nameof(test);
1113
const string t = nameof(t);
1214

15+
static IEnumerable<object[]> GetTestData()
16+
{
17+
yield return new object[] { test, TextCaseType.Lower, test };
18+
yield return new object[] { test, TextCaseType.Upper, "TEST" };
19+
yield return new object[] { test, TextCaseType.None, test };
20+
yield return new object[] { test, TextCaseType.FirstUpperRestLower, "Test" };
21+
yield return new object[] { t, TextCaseType.Upper, "T" };
22+
yield return new object[] { t, TextCaseType.Lower, t };
23+
yield return new object[] { t, TextCaseType.None, t };
24+
yield return new object[] { t, TextCaseType.FirstUpperRestLower, "T" };
25+
yield return new object[] { string.Empty, TextCaseType.FirstUpperRestLower, string.Empty };
26+
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
27+
yield return new object[] { null, TextCaseType.None, null };
28+
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
29+
yield return new object[] { MockEnum.Foo, TextCaseType.Lower, "foo" };
30+
yield return new object[] { MockEnum.Bar, TextCaseType.None, "Bar" };
31+
yield return new object[] { MockEnum.Baz, TextCaseType.Upper, "BAZ" };
32+
yield return new object[] { new MockItem { Title = "Test Item", Completed = true }, TextCaseType.Upper, "TEST ITEM IS COMPLETED" };
33+
}
34+
1335
[Theory]
14-
[InlineData(test, TextCaseType.Lower, test)]
15-
[InlineData(test, TextCaseType.Upper, "TEST")]
16-
[InlineData(test, TextCaseType.None, test)]
17-
[InlineData(test, TextCaseType.FirstUpperRestLower, "Test")]
18-
[InlineData(t, TextCaseType.Upper, "T")]
19-
[InlineData(t, TextCaseType.Lower, t)]
20-
[InlineData(t, TextCaseType.None, t)]
21-
[InlineData(t, TextCaseType.FirstUpperRestLower, "T")]
22-
[InlineData("", TextCaseType.FirstUpperRestLower, "")]
36+
[MemberData(nameof(GetTestData))]
2337
[InlineData(null, null, null)]
24-
public void TextCaseConverter(object value, object comparedValue, object expectedResult)
38+
public void TextCaseConverterWithParameter(object? value, object? comparedValue, object? expectedResult)
2539
{
2640
var textCaseConverter = new TextCaseConverter();
2741

28-
var result = textCaseConverter.Convert(value, typeof(TextCaseConverter_Tests), comparedValue, CultureInfo.CurrentCulture);
42+
var result = textCaseConverter.Convert(value, typeof(string), comparedValue, CultureInfo.CurrentCulture);
2943

3044
Assert.Equal(result, expectedResult);
3145
}
3246

3347
[Theory]
34-
[InlineData(0)]
35-
[InlineData(int.MinValue)]
36-
[InlineData(double.MaxValue)]
37-
public void InValidConverterValuesThrowArgumenException(object value)
48+
[MemberData(nameof(GetTestData))]
49+
public void TextCaseConverterWithExplicitType(object? value, TextCaseType textCaseType, object? expectedResult)
3850
{
39-
var textCaseConverter = new TextCaseConverter();
51+
var textCaseConverter = new TextCaseConverter
52+
{
53+
Type = textCaseType
54+
};
55+
56+
var result = textCaseConverter.Convert(value, typeof(string), null, CultureInfo.CurrentCulture);
4057

41-
Assert.Throws<ArgumentException>(() => textCaseConverter.Convert(value, typeof(TextCaseConverter_Tests), null, CultureInfo.CurrentCulture));
58+
Assert.Equal(result, expectedResult);
4259
}
4360
}
4461
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Xamarin.CommunityToolkit.UnitTests.Mocks
2+
{
3+
public enum MockEnum
4+
{
5+
Foo,
6+
Bar,
7+
Baz
8+
}
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Xamarin.CommunityToolkit.UnitTests.Mocks
2+
{
3+
public class MockItem
4+
{
5+
public string? Title { get; set; }
6+
7+
public bool Completed { get; set; }
8+
9+
public override string ToString() => Completed ?
10+
$"{Title} is completed" : $"{Title} has yet to be completed";
11+
}
12+
}

src/CommunityToolkit/Xamarin.CommunityToolkit/Converters/TextCaseConverter.shared.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,19 @@ public class TextCaseConverter : ValueConverterExtension, IValueConverter
2525
/// <param name="culture">The culture to use in the converter. This is not implemented.</param>
2626
/// <returns>The converted text representation with the desired casing.</returns>
2727
public object? Convert(object? value, Type? targetType, object? parameter, CultureInfo? culture)
28-
=> value == null || value is string || value is char
29-
? Convert(value?.ToString(), parameter)
30-
: throw new ArgumentException("Value is neither a string nor a char", nameof(value));
28+
{
29+
var str = value?.ToString();
30+
if (str == null || string.IsNullOrWhiteSpace(str))
31+
return str;
32+
33+
return GetParameter(parameter) switch
34+
{
35+
TextCaseType.Lower => str.ToLowerInvariant(),
36+
TextCaseType.Upper => str.ToUpperInvariant(),
37+
TextCaseType.FirstUpperRestLower => str.Substring(0, 1).ToUpperInvariant() + str.ToString().Substring(1).ToLowerInvariant(),
38+
_ => str
39+
};
40+
}
3141

3242
/// <summary>
3343
/// This method is not implemented and will throw a <see cref="NotImplementedException"/>.
@@ -37,18 +47,10 @@ public class TextCaseConverter : ValueConverterExtension, IValueConverter
3747
/// <param name="parameter">N/A</param>
3848
/// <param name="culture">N/A</param>
3949
/// <returns>N/A</returns>
40-
public object ConvertBack(object? value, Type? targetType, object? parameter, CultureInfo? culture)
50+
public object ConvertBack(object? value, Type? targetType, object? parameter, CultureInfo? culture)
4151
=> throw new NotImplementedException();
4252

43-
object? Convert(string? value, object? parameter) => GetParameter(parameter) switch
44-
{
45-
TextCaseType.Lower => value?.ToLowerInvariant(),
46-
TextCaseType.Upper => value?.ToUpperInvariant(),
47-
TextCaseType.FirstUpperRestLower when value != null && !string.IsNullOrWhiteSpace(value) => value.Substring(0, 1).ToUpperInvariant() + value.Substring(1).ToLowerInvariant(),
48-
_ => value
49-
};
50-
51-
TextCaseType GetParameter(object? parameter) => parameter == null ? Type : parameter switch
53+
TextCaseType GetParameter(object? parameter) => parameter switch
5254
{
5355
TextCaseType type => type,
5456
string typeString => Enum.TryParse(typeString, out TextCaseType result)
@@ -57,7 +59,7 @@ public object ConvertBack(object? value, Type? targetType, object? parameter, Cu
5759
int typeInt => Enum.IsDefined(typeof(TextCaseType), typeInt)
5860
? (TextCaseType)typeInt
5961
: throw new ArgumentException("Cannot convert integer to text case enum value", nameof(parameter)),
60-
_ => TextCaseType.None,
62+
_ => Type,
6163
};
6264
}
6365
}

src/CommunityToolkit/Xamarin.CommunityToolkit/Converters/TextCaseType.shared.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public enum TextCaseType
1313

1414
/// <summary>Convert to lowercase</summary>
1515
Lower,
16+
17+
/// <summary>Converts the first letter to upper only</summary>
1618
FirstUpperRestLower,
1719
}
1820
}

0 commit comments

Comments
 (0)