make unit test easier to extend (#296)
This commit is contained in:
parent
2958381b54
commit
af28b87660
|
@ -19,8 +19,11 @@ namespace StardewModdingAPI.Tests
|
||||||
/// <summary>A token structure type.</summary>
|
/// <summary>A token structure type.</summary>
|
||||||
public enum TokenType
|
public enum TokenType
|
||||||
{
|
{
|
||||||
/// <summary>The tokens are passed in a dictionary.</summary>
|
/// <summary>The tokens are passed in a string/object dictionary.</summary>
|
||||||
Dictionary,
|
DictionaryStringObject,
|
||||||
|
|
||||||
|
/// <summary>The tokens are passed in a string/string dictionary.</summary>
|
||||||
|
DictionaryStringString,
|
||||||
|
|
||||||
/// <summary>The tokens are passed in an anonymous object.</summary>
|
/// <summary>The tokens are passed in an anonymous object.</summary>
|
||||||
AnonymousObject
|
AnonymousObject
|
||||||
|
@ -190,7 +193,7 @@ namespace StardewModdingAPI.Tests
|
||||||
** Translation tokens
|
** Translation tokens
|
||||||
****/
|
****/
|
||||||
[Test(Description = "Assert that multiple translation tokens are replaced correctly regardless of the token structure.")]
|
[Test(Description = "Assert that multiple translation tokens are replaced correctly regardless of the token structure.")]
|
||||||
public void Translation_Tokens([Values(TokenType.AnonymousObject, TokenType.Dictionary)] TokenType tokenType)
|
public void Translation_Tokens([Values(TokenType.AnonymousObject, TokenType.DictionaryStringObject, TokenType.DictionaryStringString)] TokenType tokenType)
|
||||||
{
|
{
|
||||||
// arrange
|
// arrange
|
||||||
string start = Guid.NewGuid().ToString("N");
|
string start = Guid.NewGuid().ToString("N");
|
||||||
|
@ -207,10 +210,14 @@ namespace StardewModdingAPI.Tests
|
||||||
translation = translation.Tokens(new { start, middle, end });
|
translation = translation.Tokens(new { start, middle, end });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TokenType.Dictionary:
|
case TokenType.DictionaryStringObject:
|
||||||
translation = translation.Tokens(new Dictionary<string, object> { ["start"] = start, ["middle"] = middle, ["end"] = end });
|
translation = translation.Tokens(new Dictionary<string, object> { ["start"] = start, ["middle"] = middle, ["end"] = end });
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TokenType.DictionaryStringString:
|
||||||
|
translation = translation.Tokens(new Dictionary<string, string> { ["start"] = start, ["middle"] = middle, ["end"] = end });
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"Unknown token type {tokenType}.");
|
throw new NotSupportedException($"Unknown token type {tokenType}.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace StardewModdingAPI
|
namespace StardewModdingAPI
|
||||||
|
@ -82,37 +83,41 @@ namespace StardewModdingAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Replace tokens in the text like <c>{{value}}</c> with the given values. Returns a new instance.</summary>
|
/// <summary>Replace tokens in the text like <c>{{value}}</c> with the given values. Returns a new instance.</summary>
|
||||||
/// <param name="tokens">An anonymous object containing token key/value pairs, like <c>new { value = 42, name = "Cranberries" }</c>.</param>
|
/// <param name="tokens">An object containing token key/value pairs. This can be an anonymous object (like <c>new { value = 42, name = "Cranberries" }</c>) or a dictionary of token values.</param>
|
||||||
/// <exception cref="ArgumentNullException">The <paramref name="tokens"/> argument is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException">The <paramref name="tokens"/> argument is <c>null</c>.</exception>
|
||||||
public Translation Tokens(object tokens)
|
public Translation Tokens(object tokens)
|
||||||
{
|
{
|
||||||
if (tokens == null)
|
if (tokens == null)
|
||||||
throw new ArgumentNullException(nameof(tokens));
|
throw new ArgumentNullException(nameof(tokens));
|
||||||
|
|
||||||
IDictionary<string, object> dictionary = tokens
|
// get dictionary of tokens
|
||||||
.GetType()
|
IDictionary<string, string> tokenLookup = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
|
||||||
.GetProperties()
|
{
|
||||||
.ToDictionary(
|
// from dictionary
|
||||||
p => p.Name,
|
if (tokens is IDictionary inputLookup)
|
||||||
p => p.GetValue(tokens)
|
{
|
||||||
);
|
foreach (DictionaryEntry entry in inputLookup)
|
||||||
return this.Tokens(dictionary);
|
{
|
||||||
|
string key = entry.Key?.ToString().Trim();
|
||||||
|
if (key != null)
|
||||||
|
tokenLookup[key] = entry.Value?.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Replace tokens in the text like <c>{{value}}</c> with the given values. Returns a new instance.</summary>
|
// from object properties
|
||||||
/// <param name="tokens">A dictionary containing token key/value pairs.</param>
|
else
|
||||||
/// <exception cref="ArgumentNullException">The <paramref name="tokens"/> argument is <c>null</c>.</exception>
|
|
||||||
public Translation Tokens(IDictionary<string, object> tokens)
|
|
||||||
{
|
{
|
||||||
if (tokens == null)
|
foreach (PropertyInfo prop in tokens.GetType().GetProperties())
|
||||||
throw new ArgumentNullException(nameof(tokens));
|
tokenLookup[prop.Name] = prop.GetValue(tokens)?.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tokens = tokens.ToDictionary(p => p.Key.Trim(), p => p.Value, StringComparer.InvariantCultureIgnoreCase);
|
// format translation
|
||||||
string text = Regex.Replace(this.Text, @"{{([ \w\.\-]+)}}", match =>
|
string text = Regex.Replace(this.Text, @"{{([ \w\.\-]+)}}", match =>
|
||||||
{
|
{
|
||||||
string key = match.Groups[1].Value.Trim();
|
string key = match.Groups[1].Value.Trim();
|
||||||
return tokens.TryGetValue(key, out object value)
|
return tokenLookup.TryGetValue(key, out string value)
|
||||||
? value?.ToString()
|
? value
|
||||||
: match.Value;
|
: match.Value;
|
||||||
});
|
});
|
||||||
return new Translation(this.ModName, this.Locale, this.Key, text);
|
return new Translation(this.ModName, this.Locale, this.Key, text);
|
||||||
|
|
Loading…
Reference in New Issue