mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 02:24:30 +08:00
fix(localization): 修复紧凑数字格式化器处理未知选项的行为
- 修改 CompactNumberLocalizationFormatter 中 TryApplyOption 方法的返回逻辑 - 当键名未知时现在返回 true 而不是 false,允许忽略未知选项 - 更新 NumericDisplayFormatter 使用 ResolveRule 方法来确定格式化规则 - 添加对不同数值显示风格的支持和验证 - 在集成测试中添加未知选项的测试用例以验证正确行为 - 改进 NumericSuffixFormatRule 的文档注释以更清楚地描述功能
This commit is contained in:
parent
5996ecf5f3
commit
fca3808657
@ -52,6 +52,7 @@ public class LocalizationIntegrationTests
|
||||
"status.health": "Health: {current}/{max}",
|
||||
"status.gold": "Gold: {gold:compact}",
|
||||
"status.damage": "Damage: {damage:compact:maxDecimals=2}",
|
||||
"status.unknownCompact": "Gold: {gold:compact:maxDecimalss=2}",
|
||||
"status.invalidCompact": "Gold: {gold:compact:maxDecimals=abc}"
|
||||
}
|
||||
""");
|
||||
@ -63,6 +64,7 @@ public class LocalizationIntegrationTests
|
||||
"status.health": "生命值: {current}/{max}",
|
||||
"status.gold": "金币: {gold:compact}",
|
||||
"status.damage": "伤害: {damage:compact:maxDecimals=2}",
|
||||
"status.unknownCompact": "金币: {gold:compact:maxDecimalss=2}",
|
||||
"status.invalidCompact": "金币: {gold:compact:maxDecimals=abc}"
|
||||
}
|
||||
""");
|
||||
@ -134,6 +136,16 @@ public class LocalizationIntegrationTests
|
||||
Assert.That(damage, Is.EqualTo("Damage: 1.23K"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetString_WithUnknownCompactFormatterArgs_ShouldIgnoreUnknownOptions()
|
||||
{
|
||||
var gold = _manager!.GetString("common", "status.unknownCompact")
|
||||
.WithVariable("gold", 1_250)
|
||||
.Format();
|
||||
|
||||
Assert.That(gold, Is.EqualTo("Gold: 1.3K"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetString_WithInvalidCompactFormatterArgs_ShouldFallbackToDefaultFormatting()
|
||||
{
|
||||
|
||||
@ -146,7 +146,7 @@ public sealed class CompactNumberLocalizationFormatter : ILocalizationFormatter
|
||||
/// <param name="minDecimalPlaces">最小小数位数的引用参数</param>
|
||||
/// <param name="trimTrailingZeros">是否去除尾随零的引用参数</param>
|
||||
/// <param name="useGroupingBelowThreshold">是否在阈值以下使用分组的引用参数</param>
|
||||
/// <returns>如果键名有效且值成功解析则返回true;如果键名无效或值解析失败则返回false</returns>
|
||||
/// <returns>如果值成功解析或键名未知则返回true;如果键名已知但值解析失败则返回false</returns>
|
||||
private static bool TryApplyOption(
|
||||
string key,
|
||||
string value,
|
||||
@ -161,7 +161,7 @@ public sealed class CompactNumberLocalizationFormatter : ILocalizationFormatter
|
||||
"minDecimals" => int.TryParse(value, out minDecimalPlaces),
|
||||
"trimZeros" => bool.TryParse(value, out trimTrailingZeros),
|
||||
"grouping" => bool.TryParse(value, out useGroupingBelowThreshold),
|
||||
_ => false
|
||||
_ => true
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@ public sealed class NumericDisplayFormatter : INumericDisplayFormatter
|
||||
}
|
||||
|
||||
var resolvedOptions = NormalizeOptions(options);
|
||||
var rule = resolvedOptions.Rule ?? _defaultRule;
|
||||
var rule = ResolveRule(resolvedOptions);
|
||||
|
||||
if (rule.TryFormat(value, resolvedOptions, out var result))
|
||||
{
|
||||
@ -113,6 +113,22 @@ public sealed class NumericDisplayFormatter : INumericDisplayFormatter
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private INumericFormatRule ResolveRule(NumericFormatOptions options)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
|
||||
if (options.Rule is not null)
|
||||
{
|
||||
return options.Rule;
|
||||
}
|
||||
|
||||
return options.Style switch
|
||||
{
|
||||
NumericDisplayStyle.Compact => _defaultRule,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(options), options.Style, "不支持的数值显示风格。")
|
||||
};
|
||||
}
|
||||
|
||||
private static string FormatFallback(object value, IFormatProvider? provider)
|
||||
{
|
||||
return value switch
|
||||
|
||||
@ -33,7 +33,7 @@ public sealed class NumericSuffixFormatRule : INumericFormatRule
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 默认国际缩写规则。
|
||||
/// 默认国际缩写规则,使用标准的K、M、B、T后缀表示千、百万、十亿、万亿。
|
||||
/// </summary>
|
||||
public static NumericSuffixFormatRule InternationalCompact { get; } = new(
|
||||
"compact",
|
||||
@ -44,10 +44,19 @@ public sealed class NumericSuffixFormatRule : INumericFormatRule
|
||||
new NumericSuffixThreshold(1_000_000_000_000m, "T")
|
||||
]);
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <summary>
|
||||
/// 获取此格式化规则的名称。
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <summary>
|
||||
/// 尝试将指定的数值按照当前规则进行格式化。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">数值的类型</typeparam>
|
||||
/// <param name="value">要格式化的数值</param>
|
||||
/// <param name="options">格式化选项,包含小数位数、舍入模式等设置</param>
|
||||
/// <param name="result">格式化后的字符串结果</param>
|
||||
/// <returns>如果格式化成功则返回true;如果输入无效或格式化失败则返回false</returns>
|
||||
public bool TryFormat<T>(T value, NumericFormatOptions options, out string result)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
@ -164,15 +173,13 @@ public sealed class NumericSuffixFormatRule : INumericFormatRule
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
try
|
||||
var doubleValue = (double)value;
|
||||
if (TryFormatSpecialFloatingPoint(doubleValue, options.FormatProvider, out result))
|
||||
{
|
||||
return TryFormatDouble((double)value, options, out result);
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
result = value.ToString(options.FormatProvider ?? CultureInfo.CurrentCulture);
|
||||
return true;
|
||||
}
|
||||
|
||||
return TryFormatDouble(doubleValue, options, out result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user