Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 66 additions & 11 deletions Microsoft.Toolkit.Uwp.UI/Converters/StringFormatConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Globalization;
using Windows.UI.Xaml.Data;

namespace Microsoft.Toolkit.Uwp.UI.Converters
Expand All @@ -12,13 +13,26 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
/// </summary>
public class StringFormatConverter : IValueConverter
{
/// <summary>
/// Gets or sets the CultureInfo to make converter culture sensitive. The default value is <see cref="CultureInfo.CurrentCulture"/>
/// </summary>
public CultureInfo CultureInfo { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="StringFormatConverter"/> class.
/// </summary>
public StringFormatConverter()
{
CultureInfo = CultureInfo.CurrentCulture;
}

/// <summary>
/// Return the formatted string version of the source object.
/// </summary>
/// <param name="value">Object to transform to string.</param>
/// <param name="targetType">The type of the target property, as a type reference</param>
/// <param name="parameter">An optional parameter to be used in the string.Format method.</param>
/// <param name="language">The language of the conversion (not used).</param>
/// <param name="language">The language of the conversion. If language is null or empty then <see cref="CultureInfo"/> will be used.</param>
/// <returns>Formatted string.</returns>
public object Convert(object value, Type targetType, object parameter, string language)
{
Expand All @@ -27,20 +41,13 @@ public object Convert(object value, Type targetType, object parameter, string la
return null;
}

if (parameter == null)
string formatParameter = parameter as string;
if (formatParameter == null)
{
return value;
}

try
{
return string.Format((string)parameter, value);
}
catch
{
}

return value;
return FormatToString(value, formatParameter, GetCultureInfoOrDefault(language, () => GetDefaultCultureInfo()));
}

/// <summary>
Expand All @@ -55,5 +62,53 @@ public object ConvertBack(object value, Type targetType, object parameter, strin
{
throw new NotImplementedException();
}

private object FormatToString(object value, string parameter, CultureInfo cultureInfo)
{
try
{
return string.Format(cultureInfo, parameter, value);
}
catch
{
return value;
}
}

private CultureInfo GetCultureInfoOrDefault(string language, Func<CultureInfo> getDefaultCultureInfo)
{
CultureInfo cultureInfo;
if (!TryGetCultureInfo(language, out cultureInfo))
{
cultureInfo = getDefaultCultureInfo();
}

return cultureInfo;
}

private bool TryGetCultureInfo(string language, out CultureInfo cultureInfo)
{
cultureInfo = null;
if (string.IsNullOrEmpty(language))
{
return false;
}

try
{
cultureInfo = CultureInfo.GetCultureInfo(language);

return true;
}
catch
{
return false;
}
}

private CultureInfo GetDefaultCultureInfo()
{
return CultureInfo ?? CultureInfo.InvariantCulture;
}
}
}
132 changes: 115 additions & 17 deletions UnitTests/UnitTests.UWP/Converters/Test_StringFormatConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,157 @@
using Microsoft.Toolkit.Uwp.UI.Converters;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Globalization;

namespace UnitTests.Converters
{
[TestClass]
public class Test_StringFormatConverter
{
private static readonly object NullString = null;
private const string NullLanguage = null;

private static readonly CultureInfo ConverterCultureInfo = new CultureInfo("pl-pl");
private static readonly object NullString = null;
private static readonly object NotEmptyString = "Hello, world";
private static readonly DateTime Date = DateTime.Now;
private static readonly decimal Amount = 333.4m;

[TestCategory("Converters")]
[TestMethod]
public void WhenValueIsNull_ThenReturnNull()
[DataRow(NullLanguage)]
[DataRow("en-us")]
public void WhenValueIsNull_ThenReturnNull(string language)
{
var converter = new StringFormatConverter();
var result = converter.Convert(NullString, typeof(string), NullString, "en-us");
var result = converter.Convert(NullString, typeof(string), NullString, language);
Assert.IsNull(result);
}

[TestCategory("Converters")]
[TestMethod]
public void WhenValueExistsAndParameterIsNull_ThenReturnValue()
[DataRow(NullLanguage)]
[DataRow("en-us")]
public void WhenValueExistsAndParameterIsNull_ThenReturnValue(string language)
{
var converter = new StringFormatConverter();
var result = converter.Convert(NotEmptyString, typeof(string), NullString, "en-us");
var result = converter.Convert(NotEmptyString, typeof(string), NullString, language);
Assert.AreEqual(NotEmptyString, result);
}

[TestCategory("Converters")]
[TestMethod]
public void WhenParameterIsTimeFormat_ThenReturnValueOfTimeFormat()
[DataRow(NullLanguage)]
[DataRow("en-us")]
public void WhenParameterIsInvalidFormat_ThenReturnValue(string language)
{
var converter = new StringFormatConverter();
var result = converter.Convert(Date, typeof(string), "{0:HH:mm}", "en-us");
Assert.AreEqual(Date.ToString("HH:mm"), result);
var converter = new StringFormatConverter()
{
CultureInfo = ConverterCultureInfo
};
var result = converter.Convert(Date, typeof(string), "{1:}", language);
Assert.AreEqual(Date, result);
}

[TestCategory("Converters")]
[TestMethod]
public void WhenParameterIsInvalidFormat_ThenReturnValue()
[DataRow(NullLanguage)]
[DataRow("en-us")]
public void WhenParameterIsNotAString_ThenReturnValue(string language)
{
var converter = new StringFormatConverter();
var result = converter.Convert(Date, typeof(string), "{1:}", "en-us");
Assert.AreEqual(Date, result);
var converter = new StringFormatConverter()
{
CultureInfo = ConverterCultureInfo
};
var result = converter.Convert(NotEmptyString, typeof(string), 172, language);
Assert.AreEqual(NotEmptyString, result);
}

[TestCategory("Converters")]
[TestMethod]
[DataRow("{0:ddd d MMM}", "ddd d MMM")]
[DataRow("{0:HH:mm}", "HH:mm")]
[DataRow("{0:hh:mm:ss tt}", "hh:mm:ss tt")]
public void WhenValueIsDateTimeAndLanguageIsUnknownAndCultureInfoIsNotSet_ThenReturnValueOfTimeInInvariantCultureFormat(string converterParameter, string expectedFormat)
{
var converter = new StringFormatConverter()
{
CultureInfo = null
};
var result = converter.Convert(Date, typeof(string), converterParameter, NullLanguage);
Assert.AreEqual(Date.ToString(expectedFormat, CultureInfo.InvariantCulture), result);
}

[TestCategory("Converters")]
[TestMethod]
public void WhenParameterIsNotAString_ThenReturnValue()
[DataRow("{0:ddd d MMM}", "ddd d MMM")]
[DataRow("{0:HH:mm}", "HH:mm")]
[DataRow("{0:hh:mm:ss tt}", "hh:mm:ss tt")]
public void WhenValueIsDateTimeAndLanguageIsUnknownAndCultureInfoIsSet_ThenReturnValueOfTimeInConverterCultureInfoFormat(string converterParameter, string expectedFormat)
{
var converter = new StringFormatConverter();
var result = converter.Convert(NotEmptyString, typeof(string), 172, "en-us");
Assert.AreEqual(NotEmptyString, result);
var converter = new StringFormatConverter()
{
CultureInfo = ConverterCultureInfo
};
var result = converter.Convert(Date, typeof(string), converterParameter, NullLanguage);
Assert.AreEqual(Date.ToString(expectedFormat, ConverterCultureInfo), result);
}

[TestCategory("Converters")]
[TestMethod]
[DataRow("en-us", "{0:ddd d MMM}", "ddd d MMM")]
[DataRow("en-us", "{0:HH:mm}", "HH:mm")]
[DataRow("en-us", "{0:hh:mm:ss tt}", "hh:mm:ss tt")]
public void WhenValueIsDateTimeAndLanguageIsWellKnownAndCultureInfoIsSet_ThenReturnValueOfTimeInLanguageCultureFormat(string language, string converterParameter, string expectedFormat)
{
var converter = new StringFormatConverter()
{
CultureInfo = ConverterCultureInfo,
};
var result = converter.Convert(Date, typeof(string), converterParameter, language);
Assert.AreEqual(Date.ToString(expectedFormat, CultureInfo.GetCultureInfo(language)), result);
}

[TestCategory("Converters")]
[TestMethod]
[DataRow("{0:C2}", "C2")]
[DataRow("{0:E}", "E")]
public void WhenValueIsDecimalAndLanguageIsUnknownAndCultureInfoIsNotSet_ThenReturnValueOfDecimalInInvariantCultureFormat(string converterParameter, string expectedFormat)
{
var converter = new StringFormatConverter()
{
CultureInfo = null
};
var result = converter.Convert(Amount, typeof(string), converterParameter, NullLanguage);
Assert.AreEqual(Amount.ToString(expectedFormat, CultureInfo.InvariantCulture), result);
}

[TestCategory("Converters")]
[TestMethod]
[DataRow("{0:C2}", "C2")]
[DataRow("{0:E}", "E")]
public void WhenValueIsDecimalAndLanguageIsUnknownAndCultureInfoIsSet_ThenReturnValueOfDecimalInConverterCultureInfoFormat(string converterParameter, string expectedFormat)
{
var converter = new StringFormatConverter()
{
CultureInfo = ConverterCultureInfo
};
var result = converter.Convert(Amount, typeof(string), converterParameter, NullLanguage);
Assert.AreEqual(Amount.ToString(expectedFormat, ConverterCultureInfo), result);
}

[TestCategory("Converters")]
[TestMethod]
[DataRow("en-us", "{0:C2}", "C2")]
[DataRow("en-us", "{0:E}", "E")]
[DataRow("fr-FR", "{0:E}", "E")]
public void WhenValueIsDecimalAndLanguageIsWellKnownAndCultureInfoIsSet_ThenReturnValueOfDecimalInLanguageCultureFormat(string language, string converterParameter, string expectedFormat)
{
var converter = new StringFormatConverter()
{
CultureInfo = ConverterCultureInfo,
};
var result = converter.Convert(Amount, typeof(string), converterParameter, language);
Assert.AreEqual(Amount.ToString(expectedFormat, CultureInfo.GetCultureInfo(language)), result);
}
}
}