You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
9.9 KiB
C#


using OptionStudy.UnitApp.Next;
namespace OptionStudy.Next
{
/// <summary>
/// 命令行 配置源
/// 命令行参数分为
/// 单参数:用=将参数名和参数值按以下形式指定
/// {name}={value}
/// {prefix}{name}={value} prefix目前支持三种 “/”“--”“-”,其中“-”需配合 命令行参数映射一起使用
/// 双参数:使用 空格 将参数名和参数值隔开的形式,形如 {name}={value} 或 {prefix}{name}={value}
/// </summary>
public class CommandLineConfigurationSourceTest : IDisposable
{
private readonly ITestOutputHelper testOutput;
public CommandLineConfigurationSourceTest(ITestOutputHelper testOutputHelper)
{
this.testOutput = testOutputHelper;
}
/// <summary>
/// 创建 CommandLineConfigurationProvider
/// </summary>
[Fact]
public void Create_CommandLineConfigurationProvider_Test()
{
var args = new string[]
{
"AppName=argAppName",
"/AppVersion=1.1.1.1"
};
var cmdLineProvier = new CommandLineConfigurationProvider(args);
cmdLineProvier.Load();
var childKeys = cmdLineProvier.GetChildKeys(new string[0],null);
cmdLineProvier.TryGet("AppName", out string? appName);
cmdLineProvier.TryGet("AppVersion", out string? appVersion);
Assert.Equal(2,childKeys.Count());
Assert.Equal("argAppName", appName);
Assert.Equal("1.1.1.1", appVersion);
}
/// <summary>
/// 使用 CommandLineConfiguration
/// </summary>
[Fact]
public void Build_CommandLineConfiguration_Test()
{
var args = new string[]
{
"AppName=argAppName",
"/AppVersion=1.1.1.1",
"--EMail:ReceiveAddress=arg@163.com",
"--EMail:Recipient=arg",
};
var root = new ConfigurationBuilder().AddCommandLine(args).Build();
var option = root.Get<AppOption>();
Assert.NotNull(option);
Assert.Equal("argAppName",option.AppName);
Assert.Equal(new Version(1,1,1,1), option.AppVersion);
Assert.Equal("arg@163.com", option.EMail?.ReceiveAddress);
Assert.Equal("arg", option.EMail?.Recipient);
}
/// <summary>
/// 忽略中间不规范的值
/// </summary>
[Fact]
public void IgnoreValuesInMiddle_Test()
{
var args = new string[]
{
"Key1=Value1",
"--Key2=Value2",
"/Key3=Value3",
"Bogus1", //忽略,只有一个名没有值
"--Key4", "Value4",
"Bogus2", //忽略,只有一个名没有值
"/Key5", "Value5",
"Bogus3" //忽略,只有一个名没有值
};
var root = new ConfigurationBuilder().AddCommandLine(args).Build();
Assert.Equal("Value1", root.GetValue<string>("Key1"));
Assert.Equal("Value2", root.GetValue<string>("Key2"));
Assert.Equal("Value3", root.GetValue<string>("Key3"));
Assert.Equal("Value4", root.GetValue<string>("Key4"));
Assert.Equal("Value5", root.GetValue<string>("Key5"));
Assert.Equal(5, root.GetChildren().Count());
}
/// <summary>
/// 使用参数映射:-前辍必需配合参数映射一起使用
/// </summary>
[Fact]
public void Use_SwitchMappings_Test()
{
var args = new string[]
{
"-K1=Value1",
"--Key2=Value2",
"/Key3=Value3",
"--Key4", "Value4",
"/Key5", "Value5",
"/Key6=Value6"
};
var switchMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "-K1", "LongKey1" },
{ "--Key2", "SuperLongKey2" },
{ "--Key6", "SuchALongKey6"}
};
var root = new ConfigurationBuilder().AddCommandLine(args,switchMappings).Build();
Assert.Equal("Value1", root.GetValue<string>("LongKey1"));
Assert.Equal("Value2", root.GetValue<string>("SuperLongKey2"));
Assert.Equal("Value3", root.GetValue<string>("Key3"));
Assert.Equal("Value4", root.GetValue<string>("Key4"));
Assert.Equal("Value5", root.GetValue<string>("Key5"));
Assert.Equal("Value6", root.GetValue<string>("SuchALongKey6"));
}
/// <summary>
/// 参数映射错误时,抛出异常
/// </summary>
[Fact]
public void ThrowException_SwitchMappings_HasError_Test()
{
// Arrange
var args = new string[]
{
"-K1=Value1", //映射被错过
"--Key2=Value2",
"/Key3=Value3",
"--Key4", "Value4",
"/Key5", "Value5"
};
var switchMappings = new Dictionary<string, string>(StringComparer.Ordinal)
{
{ "--KEY1", "LongKey1" },
{ "--key1", "SuperLongKey1" },
{ "-Key2", "LongKey2" },
{ "-KEY2", "LongKey2"}
};
// Find out the duplicate expected be be reported
var expectedDup = string.Empty;
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var mapping in switchMappings)
{
if (set.Contains(mapping.Key))
{
expectedDup = mapping.Key;
break;
}
set.Add(mapping.Key);
}
var expectedMsg = new ArgumentException("switchMappings").Message;
// Act
var exception = Assert.Throws<ArgumentException>
(
() => new CommandLineConfigurationProvider(args, switchMappings)
);
// Assert
Assert.Contains(expectedMsg, exception.Message);
}
/// <summary>
/// 包含无效键名时,抛出异常
/// </summary>
[Fact]
public void ThrowException_SwitchMappings_ContainInvalidKey_Test()
{
var args = new string[]
{
"-K1=Value1",
"--Key2=Value2",
"/Key3=Value3",
"--Key4", "Value4",
"/Key5", "Value5"
};
var switchMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "-K1", "LongKey1" },
{ "--Key2", "SuperLongKey2" },
{ "/Key3", "AnotherSuperLongKey3" }
};
Assert.Throws<ArgumentException>
(
() => new CommandLineConfigurationProvider(args, switchMappings)
);
}
/// <summary>
/// 命令行参数为null,抛出异常
/// </summary>
[Fact]
public void ThrowException_NullIsPassedToConstructorAsArgs_Test()
{
string[] args = null;
var expectedMsg = new ArgumentNullException("args").Message;
var exception = Assert.Throws<ArgumentNullException>(() => new CommandLineConfigurationProvider(args));
Assert.Equal(expectedMsg, exception.Message);
}
/// <summary>
/// 键重复时覆盖值
/// </summary>
[Fact]
public void OverrideValueWhenKeyIsDuplicated_Test()
{
var args = new string[]
{
"/Key1=Value1",
"--Key1=Value2"
};
var cmdLineConfig = new CommandLineConfigurationProvider(args);
cmdLineConfig.Load();
cmdLineConfig.TryGet("Key1", out string? value1);
Assert.Equal("Value2", value1);
}
/// <summary>
/// 忽略缺少Key的值
/// </summary>
[Fact]
public void IgnoreWhenValueForAKeyIsMissing_Test()
{
var args = new string[]
{
"--Key1", "Value1",
"/Key2" /* The value for Key2 is missing here */
};
var cmdLineConfig = new CommandLineConfigurationProvider(args);
cmdLineConfig.Load();
cmdLineConfig.TryGet("Key1", out string? value1);
Assert.Single(cmdLineConfig.GetChildKeys(new string[0], null));
Assert.Equal("Value1", value1);
}
/// <summary>
/// 忽略无法识别的参数
/// </summary>
[Fact]
public void IgnoreWhenAnArgumentCannotBeRecognized_Test()
{
var args = new string[]
{
"ArgWithoutPrefixAndEqualSign"
};
var cmdLineConfig = new CommandLineConfigurationProvider(args);
cmdLineConfig.Load();
Assert.Empty(cmdLineConfig.GetChildKeys(new string[0], null));
}
/// <summary>
/// 忽略未被映射的参数
/// 如果没有映射则异常有映射但key不在映射中时则忽略
/// </summary>
[Fact]
public void IgnoreWhenShortSwitchNotDefined_Test()
{
var args = new string[]
{
"-Key1", "Value1",
};
var switchMappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "-Key2", "LongKey2" }
};
var cmdLineConfig = new CommandLineConfigurationProvider(args, switchMappings);
cmdLineConfig.Load();
Assert.Empty(cmdLineConfig.GetChildKeys(new string[0], ""));
}
public void Dispose()
{
}
}
}