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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()
{
}
}
}