using System;
using System.Collections.Generic;
using VRage.Game.ModAPI.Ingame.Utilities;
using Xunit;
using P = AutoMiningScript.Program;
namespace AutoMiningScript.Tests
{
public class ParameterLocalizationTests
{
static bool Chinese { get { return P.L.Language == "zh-CN"; } }
static string Field(string section, string key, string value)
{ return "[" + P.Settings.SectionName(section) + "]\n" + P.Settings.ParameterName(key) + "=" + value + "\n"; }
[Theory]
[InlineData("fleet")]
[InlineData("miner")]
[InlineData("marker")]
[InlineData("watchdog")]
public void FreshTemplatesContainLocalizedKeysEnumsAndNames(string role)
{
string id = P.Settings.DefaultId(role, 421);
string text = P.Settings.Template(role, id);
var ini = new MyIni(); Assert.True(ini.TryParse(text));
var keys = new List<MyIniKey>(); ini.GetKeys(keys);
if (Chinese)
{
Assert.Equal(role == "fleet" ? "主控" : P.Settings.DefaultName(role) + "-421", id);
foreach (var key in keys)
{
Assert.DoesNotMatch("[a-zA-Z]", key.Section);
Assert.DoesNotMatch("[a-zA-Z]", key.Name);
Assert.DoesNotMatch("[a-zA-Z]", ini.Get(key).ToString());
}
}
else Assert.DoesNotMatch("[\\p{IsCJKUnifiedIdeographs}]", text);
var settings = new P.Settings(text, role, "fallback");
Assert.Equal(id, settings.Id);
Assert.Equal("Iron,Nickel,Cobalt", settings.Text("Mining", "TargetOres", ""));
Assert.Equal("Debug", settings.Text("Display", "Font", ""));
Assert.True(settings.Flag("Hardware", "AutoCalibrate", false));
Assert.True(settings.Flag("Display", "BuiltIn", false));
Assert.True(settings.Flag("Display", "AutoPage", false));
Assert.False(settings.Flag("Watchdog", "Enabled", true));
Assert.Equal(.05, settings.Number("Cargo", "DepartureFill", 0, 0, 1));
}
[Fact]
public void OldIncompleteConfigurationKeepsLegacyIdentityDefaults()
{
var settings = new P.Settings("[Flight]\nCruiseSpeed=14\n[Hardware]\nGroup=My Mining Rig\n", "miner", "MiXeD-id");
Assert.Equal("MiXeD-id", settings.Id); Assert.Equal("mining", settings.FleetId); Assert.Equal("base", settings.BaseId);
Assert.Equal("My Mining Rig", settings.Text("Hardware", "Group", ""));
}
[Fact]
public void AliasesNormalizeAtConfigurationBoundaryWithoutTranslatingUserIdentity()
{
var settings = new P.Settings(Field("System", "Id", "Deep Space 一号-MiXeD") +
Field("Hardware", "Controller", "My Gold Controller") + Field("Mining", "TargetOres", P.Settings.ValueName("Mining", "TargetOres", "Gold,Iron,Ice")), "miner", "unused");
Assert.Equal("Deep Space 一号-MiXeD", settings.Id);
Assert.Equal("My Gold Controller", settings.Text("Hardware", "Controller", ""));
Assert.Equal("Gold,Iron,Ice", settings.Text("Mining", "TargetOres", ""));
}
[Fact]
public void MixedLanguageConflictsAreReportedBeforeAnyNormalization()
{
if (!Chinese) return;
var ini = new MyIni(); Assert.True(ini.TryParse("[Cargo]\nDepartureFill=0.05\n" + Field("Cargo", "DepartureFill", "0.1")));
string before = ini.ToString();
var error = Assert.Throws<ArgumentException>(() => P.Settings.NormalizeIni(ini));
Assert.Contains("DepartureFill", error.Message); Assert.Contains("起飞载荷上限", error.Message);
Assert.Equal(before, ini.ToString());
}
[Fact]
public void EqualAliasesAndBooleanRepresentationsAreIdempotent()
{
if (!Chinese) return;
var ini = new MyIni(); Assert.True(ini.TryParse("[Display]\nAutoPage=true\n[显示]\n自动翻页=是\n[未管理]\n备注=原样保留\n"));
P.Settings.NormalizeIni(ini); string once = ini.ToString(); P.Settings.NormalizeIni(ini);
Assert.Equal(once, ini.ToString()); Assert.True(ini.Get("Display", "AutoPage").ToBoolean());
Assert.Equal("原样保留", ini.Get("未管理", "备注").ToString());
}
[Fact]
public void LocalizedScreensNormalizeDynamicSectionsAndKeepBoundId()
{
var ini = new MyIni(); Assert.True(ini.TryParse(
Field("AMS.Screen.2", "Page", P.Settings.ValueName("AMS.Screen", "Page", "diagnostics")) +
P.Settings.ParameterName("Enabled") + "=" + P.Settings.ValueName("AMS.Screen", "Enabled", "true") + "\n" +
P.Settings.ParameterName("Miner") + "=My Miner CASE\n" + P.Settings.ParameterName("Font") + "=" + P.Settings.ValueName("AMS.Screen", "Font", "Monospace")));
P.Settings.NormalizeIni(ini);
Assert.True(ini.ContainsSection("AMS.Screen.2"));
Assert.Equal("diagnostics", ini.Get("AMS.Screen.2", "Page").ToString());
Assert.Equal("My Miner CASE", ini.Get("AMS.Screen.2", "Miner").ToString());
Assert.Equal("Monospace", ini.Get("AMS.Screen.2", "Font").ToString());
Assert.True(ini.Get("AMS.Screen.2", "Enabled").ToBoolean());
}
[Theory]
[InlineData("Number", "DepartureFill", "NaN")]
[InlineData("Integer", "MaxMiners", "2.5")]
[InlineData("Flag", "AutoPage", "invalid")]
public void InvalidLocalizedSettingsReportLocalizedField(string type, string key, string value)
{
string section = type == "Number" ? "Cargo" : type == "Integer" ? "Fleet" : "Display";
var settings = new P.Settings(Field(section, key, value), "miner", "unit");
var error = Assert.Throws<ArgumentException>(() => { if (type == "Number") settings.Number(section, key, .05, 0, 1); else if (type == "Integer") settings.Integer(section, key, 16, 1, 16); else settings.Flag(section, key, true); });
Assert.Contains(P.Settings.SectionName(section), error.Message); Assert.Contains(P.Settings.ParameterName(key), error.Message);
}
[Fact]
public void ChineseCommandsOnlyTranslateCommandWordsAndWholeAllTarget()
{
if (!Chinese) return;
Assert.Equal("return My Miner CASE", P.Settings.NormalizeCommand("返航 My Miner CASE"));
Assert.Equal("start all", P.Settings.NormalizeCommand("启动 全部"));
Assert.Equal("start 全部一号", P.Settings.NormalizeCommand("启动 全部一号"));
Assert.Equal("page diagnostics", P.Settings.NormalizeCommand("页面 诊断"));
Assert.Equal("page next", P.Settings.NormalizeCommand("页面 下一页"));
Assert.Equal("page stop", P.Settings.NormalizeCommand("页面 停止"));
Assert.Equal("mark 5 6 7 GPS:My Gold MINE:0:0:0: GPS:Inside:1:2:3:", P.Settings.NormalizeCommand("标点 5 6 7 GPS:My Gold MINE:0:0:0: GPS:Inside:1:2:3:"));
}
[Theory]
[InlineData(" ReTuRn Deep Space CASE ", "return Deep Space CASE")]
[InlineData("MARK 4 5 6 GPS:A:1:2:3: GPS:B:4:5:6:", "mark 4 5 6 GPS:A:1:2:3: GPS:B:4:5:6:")]
[InlineData("page CONFIG", "page config")]
public void LegacyEnglishCommandsRemainAcceptedWithoutChangingUserText(string input, string expected)
{ Assert.Equal(expected, P.Settings.NormalizeCommand(input)); }
[Fact]
public void EveryRegisteredParameterHasAUniqueLocalizedName()
{
var names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (string row in P.L.ParamKeys.Split('|'))
{ string[] pair = row.Split('='); Assert.True(names.Add(pair.Length == 2 ? pair[1] : pair[0]), row); }
}
}
}
using System;
using System.Collections.Generic;
using VRage.Game.ModAPI.Ingame.Utilities;
using Xunit;
using P = AutoMiningScript.Program;
namespace AutoMiningScript.Tests
{
public class ParameterLocalizationTests
{
static bool Chinese { get { return P.L.Language == "zh-CN"; } }
static string Field(string section, string key, string value)
{ return "[" + P.Settings.SectionName(section) + "]\n" + P.Settings.ParameterName(key) + "=" + value + "\n"; }
[Theory]
[InlineData("fleet")]
[InlineData("miner")]
[InlineData("marker")]
[InlineData("watchdog")]
public void FreshTemplatesContainLocalizedKeysEnumsAndNames(string role)
{
string id = P.Settings.DefaultId(role, 421);
string text = P.Settings.Template(role, id);
var ini = new MyIni(); Assert.True(ini.TryParse(text));
var keys = new List<MyIniKey>(); ini.GetKeys(keys);
if (Chinese)
{
Assert.Equal(role == "fleet" ? "主控" : P.Settings.DefaultName(role) + "-421", id);
foreach (var key in keys)
{
Assert.DoesNotMatch("[a-zA-Z]", key.Section);
Assert.DoesNotMatch("[a-zA-Z]", key.Name);
Assert.DoesNotMatch("[a-zA-Z]", ini.Get(key).ToString());
}
}
else Assert.DoesNotMatch("[\\p{IsCJKUnifiedIdeographs}]", text);
var settings = new P.Settings(text, role, "fallback");
Assert.Equal(id, settings.Id);
Assert.Equal("Iron,Nickel,Cobalt", settings.Text("Mining", "TargetOres", ""));
Assert.Equal("Debug", settings.Text("Display", "Font", ""));
Assert.True(settings.Flag("Hardware", "AutoCalibrate", false));
Assert.True(settings.Flag("Display", "BuiltIn", false));
Assert.True(settings.Flag("Display", "AutoPage", false));
Assert.False(settings.Flag("Watchdog", "Enabled", true));
Assert.Equal(.05, settings.Number("Cargo", "DepartureFill", 0, 0, 1));
}
[Fact]
public void OldIncompleteConfigurationKeepsLegacyIdentityDefaults()
{
var settings = new P.Settings("[Flight]\nCruiseSpeed=14\n[Hardware]\nGroup=My Mining Rig\n", "miner", "MiXeD-id");
Assert.Equal("MiXeD-id", settings.Id); Assert.Equal("mining", settings.FleetId); Assert.Equal("base", settings.BaseId);
Assert.Equal("My Mining Rig", settings.Text("Hardware", "Group", ""));
}
[Fact]
public void AliasesNormalizeAtConfigurationBoundaryWithoutTranslatingUserIdentity()
{
var settings = new P.Settings(Field("System", "Id", "Deep Space 一号-MiXeD") +
Field("Hardware", "Controller", "My Gold Controller") + Field("Mining", "TargetOres", P.Settings.ValueName("Mining", "TargetOres", "Gold,Iron,Ice")), "miner", "unused");
Assert.Equal("Deep Space 一号-MiXeD", settings.Id);
Assert.Equal("My Gold Controller", settings.Text("Hardware", "Controller", ""));
Assert.Equal("Gold,Iron,Ice", settings.Text("Mining", "TargetOres", ""));
}
[Fact]
public void MixedLanguageConflictsAreReportedBeforeAnyNormalization()
{
if (!Chinese) return;
var ini = new MyIni(); Assert.True(ini.TryParse("[Cargo]\nDepartureFill=0.05\n" + Field("Cargo", "DepartureFill", "0.1")));
string before = ini.ToString();
var error = Assert.Throws<ArgumentException>(() => P.Settings.NormalizeIni(ini));
Assert.Contains("DepartureFill", error.Message); Assert.Contains("起飞载荷上限", error.Message);
Assert.Equal(before, ini.ToString());
}
[Fact]
public void EqualAliasesAndBooleanRepresentationsAreIdempotent()
{
if (!Chinese) return;
var ini = new MyIni(); Assert.True(ini.TryParse("[Display]\nAutoPage=true\n[显示]\n自动翻页=是\n[未管理]\n备注=原样保留\n"));
P.Settings.NormalizeIni(ini); string once = ini.ToString(); P.Settings.NormalizeIni(ini);
Assert.Equal(once, ini.ToString()); Assert.True(ini.Get("Display", "AutoPage").ToBoolean());
Assert.Equal("原样保留", ini.Get("未管理", "备注").ToString());
}
[Fact]
public void LocalizedScreensNormalizeDynamicSectionsAndKeepBoundId()
{
var ini = new MyIni(); Assert.True(ini.TryParse(
Field("AMS.Screen.2", "Page", P.Settings.ValueName("AMS.Screen", "Page", "diagnostics")) +
P.Settings.ParameterName("Enabled") + "=" + P.Settings.ValueName("AMS.Screen", "Enabled", "true") + "\n" +
P.Settings.ParameterName("Miner") + "=My Miner CASE\n" + P.Settings.ParameterName("Font") + "=" + P.Settings.ValueName("AMS.Screen", "Font", "Monospace")));
P.Settings.NormalizeIni(ini);
Assert.True(ini.ContainsSection("AMS.Screen.2"));
Assert.Equal("diagnostics", ini.Get("AMS.Screen.2", "Page").ToString());
Assert.Equal("My Miner CASE", ini.Get("AMS.Screen.2", "Miner").ToString());
Assert.Equal("Monospace", ini.Get("AMS.Screen.2", "Font").ToString());
Assert.True(ini.Get("AMS.Screen.2", "Enabled").ToBoolean());
}
[Theory]
[InlineData("Number", "DepartureFill", "NaN")]
[InlineData("Integer", "MaxMiners", "2.5")]
[InlineData("Flag", "AutoPage", "invalid")]
public void InvalidLocalizedSettingsReportLocalizedField(string type, string key, string value)
{
string section = type == "Number" ? "Cargo" : type == "Integer" ? "Fleet" : "Display";
var settings = new P.Settings(Field(section, key, value), "miner", "unit");
var error = Assert.Throws<ArgumentException>(() => { if (type == "Number") settings.Number(section, key, .05, 0, 1); else if (type == "Integer") settings.Integer(section, key, 16, 1, 16); else settings.Flag(section, key, true); });
Assert.Contains(P.Settings.SectionName(section), error.Message); Assert.Contains(P.Settings.ParameterName(key), error.Message);
}
[Fact]
public void ChineseCommandsOnlyTranslateCommandWordsAndWholeAllTarget()
{
if (!Chinese) return;
Assert.Equal("return My Miner CASE", P.Settings.NormalizeCommand("返航 My Miner CASE"));
Assert.Equal("start all", P.Settings.NormalizeCommand("启动 全部"));
Assert.Equal("start 全部一号", P.Settings.NormalizeCommand("启动 全部一号"));
Assert.Equal("page diagnostics", P.Settings.NormalizeCommand("页面 诊断"));
Assert.Equal("page next", P.Settings.NormalizeCommand("页面 下一页"));
Assert.Equal("page stop", P.Settings.NormalizeCommand("页面 停止"));
Assert.Equal("mark 5 6 7 GPS:My Gold MINE:0:0:0: GPS:Inside:1:2:3:", P.Settings.NormalizeCommand("标点 5 6 7 GPS:My Gold MINE:0:0:0: GPS:Inside:1:2:3:"));
}
[Theory]
[InlineData(" ReTuRn Deep Space CASE ", "return Deep Space CASE")]
[InlineData("MARK 4 5 6 GPS:A:1:2:3: GPS:B:4:5:6:", "mark 4 5 6 GPS:A:1:2:3: GPS:B:4:5:6:")]
[InlineData("page CONFIG", "page config")]
public void LegacyEnglishCommandsRemainAcceptedWithoutChangingUserText(string input, string expected)
{ Assert.Equal(expected, P.Settings.NormalizeCommand(input)); }
[Fact]
public void EveryRegisteredParameterHasAUniqueLocalizedName()
{
var names = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (string row in P.L.ParamKeys.Split('|'))
{ string[] pair = row.Split('='); Assert.True(names.Add(pair.Length == 2 ? pair[1] : pair[0]), row); }
}
}
}