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(); ini.GetKeys(keys); Assert.DoesNotContain(keys, key => string.Equals(key.Name, "Role", StringComparison.OrdinalIgnoreCase) || key.Name == "角色"); 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(role, settings.Role); 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)); } [Theory] [InlineData("fleet")] [InlineData("miner")] [InlineData("marker")] [InlineData("watchdog")] public void CompiledRoleIgnoresLegacyValuesWithoutChangingOtherSettings(string role) { foreach (var oldValue in new[] { "miner", "FLEET", "watchdog", "", "not-a-role" }) { var text = "[System]\nRole=" + oldValue + "\nId=Existing CASE\nFleetId=My Fleet\nBaseId=My Base\n[Flight]\nCruiseSpeed=12\n"; var settings = new P.Settings(text, role, "fallback"); Assert.Equal(role, settings.Role); Assert.Equal("Existing CASE", settings.Id); Assert.Equal("My Fleet", settings.FleetId); Assert.Equal("My Base", settings.BaseId); Assert.Equal(12, settings.Number("Flight", "CruiseSpeed", 15, 1, 95)); Assert.Equal("absent", settings.Text("System", "Role", "absent")); } } [Fact] public void ConflictingOldRoleAliasesAreIgnoredBeforeOtherAliasValidation() { if (!Chinese) return; var source = "[System]\nRole=miner\n[系统]\n角色=错误角色\n编号=Existing ID\n"; var settings = new P.Settings(source, "fleet", "fallback"); Assert.Equal("fleet", settings.Role); Assert.Equal("Existing ID", settings.Id); Assert.Equal("absent", settings.Text("System", "Role", "absent")); Assert.Throws(() => new P.Settings(source + "[Cargo]\nDepartureFill=0.05\n[货物]\n起飞载荷上限=0.1\n", "fleet", "fallback")); } [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(() => 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(() => { 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(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); } } } }