From c9e843aa3b033f2f28edce124fb34b828d7f1674 Mon Sep 17 00:00:00 2001
From: DHR60 <192860629+DHR60@users.noreply.github.com>
Date: Wed, 19 Aug 2026 01:54:51 +0000
Subject: [PATCH] TUnit (#9981)
---
.github/workflows/test.yml | 13 +-
v2rayN/Directory.Packages.props | 4 +-
.../Context/CoreConfigContextBuilderTests.cs | 45 ++-
.../Singbox/CoreConfigSingboxServiceTests.cs | 290 +++++++++---------
.../V2ray/CoreConfigV2rayServiceTests.cs | 265 ++++++++--------
.../ServiceLib.Tests/Fmt/FmtHandlerTests.cs | 102 +++---
v2rayN/ServiceLib.Tests/Fmt/HyRealmTests.cs | 79 +++--
v2rayN/ServiceLib.Tests/Fmt/InnerFmtTests.cs | 21 +-
.../ServiceLib.Tests/Fmt/WireguardFmtTests.cs | 28 +-
.../Manager/CoreManagerTests.cs | 43 ++-
.../ServiceLib.Tests/ServiceLib.Tests.csproj | 29 +-
11 files changed, 448 insertions(+), 471 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9cb4496c..4dcddab6 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -9,6 +9,10 @@ on:
- 'v2rayN/ServiceLib/Handler/Fmt/**'
- '.github/workflows/test.yml'
+permissions:
+ checks: write
+ pull-requests: write
+
jobs:
test:
runs-on: ubuntu-latest
@@ -27,4 +31,11 @@ jobs:
- name: Test Code
working-directory: ./v2rayN
- run: dotnet run --project ./ServiceLib.Tests -c Release
+ run: dotnet test ./ServiceLib.Tests -c Release --no-build --results-directory ./TestResults -- --report-trx
+
+ - name: Comment PR with results
+ if: always()
+ uses: EnricoMi/publish-unit-test-result-action@v2
+ with:
+ files: ./v2rayN/TestResults/*.trx
+ comment_mode: failures
diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props
index bafc2993..ecbd8676 100644
--- a/v2rayN/Directory.Packages.props
+++ b/v2rayN/Directory.Packages.props
@@ -28,10 +28,12 @@
+
+
-
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib.Tests/CoreConfig/Context/CoreConfigContextBuilderTests.cs b/v2rayN/ServiceLib.Tests/CoreConfig/Context/CoreConfigContextBuilderTests.cs
index 10531092..73688f67 100644
--- a/v2rayN/ServiceLib.Tests/CoreConfig/Context/CoreConfigContextBuilderTests.cs
+++ b/v2rayN/ServiceLib.Tests/CoreConfig/Context/CoreConfigContextBuilderTests.cs
@@ -1,15 +1,8 @@
-using AwesomeAssertions;
-using ServiceLib.Enums;
-using ServiceLib.Handler.Builder;
-using ServiceLib.Helper;
-using ServiceLib.Models;
-using Xunit;
-
namespace ServiceLib.Tests.CoreConfig.Context;
public class CoreConfigContextBuilderTests
{
- [Fact]
+ [Test]
public async Task ResolveNodeAsync_DirectCycleDependency_ShouldFailWithCycleError()
{
var config = CoreConfigTestFactory.CreateConfig();
@@ -27,13 +20,13 @@ public class CoreConfigContextBuilderTests
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
- validatorResult.Success.Should().BeFalse();
- validatorResult.Errors.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
- context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
- context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
+ await validatorResult.Success.Should().BeFalse();
+ await validatorResult.Errors.Should().Contain(ContainsCycleDependencyMessage);
+ await context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
+ await context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
}
- [Fact]
+ [Test]
public async Task ResolveNodeAsync_IndirectCycleDependency_ShouldFailWithCycleError()
{
var config = CoreConfigTestFactory.CreateConfig();
@@ -53,14 +46,14 @@ public class CoreConfigContextBuilderTests
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
- validatorResult.Success.Should().BeFalse();
- validatorResult.Errors.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
- context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
- context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
- context.AllProxiesMap.Should().NotContainKey(groupC.IndexId);
+ await validatorResult.Success.Should().BeFalse();
+ await validatorResult.Errors.Should().Contain(ContainsCycleDependencyMessage);
+ await context.AllProxiesMap.Should().NotContainKey(groupA.IndexId);
+ await context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
+ await context.AllProxiesMap.Should().NotContainKey(groupC.IndexId);
}
- [Fact]
+ [Test]
public async Task ResolveNodeAsync_CycleWithValidBranch_ShouldSkipCycleAndKeepValidChild()
{
var config = CoreConfigTestFactory.CreateConfig();
@@ -80,14 +73,14 @@ public class CoreConfigContextBuilderTests
var (_, validatorResult) = await CoreConfigContextBuilder.ResolveNodeAsync(context, groupA, false);
- validatorResult.Success.Should().BeTrue();
- validatorResult.Errors.Should().BeEmpty();
- validatorResult.Warnings.Should().Contain(msg => ContainsCycleDependencyMessage(msg));
+ await validatorResult.Success.Should().BeTrue();
+ await validatorResult.Errors.Should().BeEmpty();
+ await validatorResult.Warnings.Should().Contain(ContainsCycleDependencyMessage);
- context.AllProxiesMap.Should().ContainKey(leaf.IndexId);
- context.AllProxiesMap.Should().ContainKey(groupA.IndexId);
- context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
- groupA.GetProtocolExtra().ChildItems.Should().Be(leaf.IndexId);
+ await context.AllProxiesMap.Should().ContainKey(leaf.IndexId);
+ await context.AllProxiesMap.Should().ContainKey(groupA.IndexId);
+ await context.AllProxiesMap.Should().NotContainKey(groupB.IndexId);
+ await groupA.GetProtocolExtra().ChildItems.Should().BeEqualTo(leaf.IndexId);
}
private static string NewId(string prefix)
diff --git a/v2rayN/ServiceLib.Tests/CoreConfig/Singbox/CoreConfigSingboxServiceTests.cs b/v2rayN/ServiceLib.Tests/CoreConfig/Singbox/CoreConfigSingboxServiceTests.cs
index f1692f7c..1055a248 100644
--- a/v2rayN/ServiceLib.Tests/CoreConfig/Singbox/CoreConfigSingboxServiceTests.cs
+++ b/v2rayN/ServiceLib.Tests/CoreConfig/Singbox/CoreConfigSingboxServiceTests.cs
@@ -1,19 +1,9 @@
-using AwesomeAssertions;
-using ServiceLib.Common;
-using ServiceLib.Enums;
-using ServiceLib.Handler.Fmt;
-using ServiceLib.Manager;
-using ServiceLib.Models;
-using ServiceLib.Models.Dto;
-using ServiceLib.Services.CoreConfig;
-using Xunit;
-
namespace ServiceLib.Tests.CoreConfig.Singbox;
public class CoreConfigSingboxServiceTests
{
- [Fact]
- public void GenerateClientConfigContent_ShouldGenerateBasicProxyConfig()
+ [Test]
+ public async Task GenerateClientConfigContent_ShouldGenerateBasicProxyConfig()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -22,17 +12,17 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
- result.Data.Should().NotBeNull();
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
+ await result.Data.Should().NotBeNull();
var singboxConfig = JsonUtils.Deserialize(result.Data!.ToString());
- singboxConfig.Should().NotBeNull();
- singboxConfig!.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "socks");
- singboxConfig.inbounds.Should().Contain(i => i.type == nameof(EInboundProtocol.mixed));
+ await singboxConfig.Should().NotBeNull();
+ await singboxConfig!.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "socks");
+ await singboxConfig.inbounds.Should().Contain(i => i.type == nameof(EInboundProtocol.mixed));
}
- [Fact]
- public void GenerateClientConfigContent_TunWithLoopbackPreSocks_ShouldKeepMixedInbound()
+ [Test]
+ public async Task GenerateClientConfigContent_TunWithLoopbackPreSocks_ShouldKeepMixedInbound()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -46,18 +36,18 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.inbounds.Should().Contain(i =>
+ await cfg.inbounds.Should().Contain(i =>
i.type == nameof(EInboundProtocol.mixed)
&& i.listen == Global.Loopback
&& i.listen_port == AppManager.Instance.GetLocalPort(EInboundProtocol.socks));
- cfg.inbounds.Should().Contain(i => i.type == "tun");
+ await cfg.inbounds.Should().Contain(i => i.type == "tun");
}
- [Fact]
- public void GenerateClientConfigContent_TunEnabled_ShouldKeepEmbeddedTunRules()
+ [Test]
+ public async Task GenerateClientConfigContent_TunEnabled_ShouldKeepEmbeddedTunRules()
{
// The embedded tun rules reject local-network noise (NetBIOS/mDNS, multicast).
// They are deserialized into List, so a schema mismatch in the
@@ -75,22 +65,22 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.route.rules.Should().Contain(
+ await cfg.route.rules.Should().Contain(
r => r.action == "reject"
&& r.network != null && r.network.Contains("udp")
&& r.port != null && r.port.Contains(5353),
"the embedded tun rules must reject mDNS/NetBIOS noise");
- cfg.route.rules.Should().Contain(
+ await cfg.route.rules.Should().Contain(
r => r.action == "reject"
&& r.ip_cidr != null && r.ip_cidr.Contains("224.0.0.0/3"),
"the embedded tun rules must reject multicast traffic");
}
- [Fact]
- public void GenerateClientConfigContent_TunEnabled_ShouldRejectTrafficToTunOwnAddresses()
+ [Test]
+ public async Task GenerateClientConfigContent_TunEnabled_ShouldRejectTrafficToTunOwnAddresses()
{
// Regression test: traffic addressed to the TUN interface's own addresses must
// never reach an outbound. auto_route hijacks the default route, so `direct`
@@ -111,17 +101,19 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var tun = cfg.inbounds.First(i => i.type == "tun");
- tun.address.Should().NotBeNullOrEmpty();
+ //tun.address.Should().NotBeNullOrEmpty();
+ await tun.address.Should().NotBeNull();
+ await tun.address.Should().NotBeEmpty();
foreach (var address in tun.address!)
{
var self = IPAddress.Parse(address.Split('/').First());
var hostBits = self.AddressFamily == AddressFamily.InterNetworkV6 ? 128 : 32;
var expected = $"{self}/{hostBits}";
- cfg.route.rules.Should().Contain(
+ await cfg.route.rules.Should().Contain(
r => r.action == "reject" && r.ip_cidr != null && r.ip_cidr.Contains(expected),
$"traffic to the TUN's own address '{address}' must be rejected, not routed");
}
@@ -131,12 +123,13 @@ public class CoreConfigSingboxServiceTests
// here leaves room for it, so a prefix match would drop system name lookups too.
var dropRule = cfg.route.rules.First(r =>
r.action == "reject" && r.method == "drop" && r.ip_cidr?.Count > 0);
- dropRule.ip_cidr!.Should().OnlyContain(c =>
- c.EndsWith("/32", StringComparison.Ordinal) || c.EndsWith("/128", StringComparison.Ordinal));
+ //dropRule.ip_cidr!.Should().OnlyContain(c =>
+ // c.EndsWith("/32", StringComparison.Ordinal) || c.EndsWith("/128", StringComparison.Ordinal));
+ await dropRule.ip_cidr.Should().All(c => c.EndsWith("/32", StringComparison.Ordinal) || c.EndsWith("/128", StringComparison.Ordinal));
}
- [Fact]
- public void GenerateClientConfigContent_BindInterface_ShouldUseDialBindInterface()
+ [Test]
+ public async Task GenerateClientConfigContent_BindInterface_ShouldUseDialBindInterface()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
config.CoreBasicItem.BindInterface = "eth0";
@@ -150,16 +143,16 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var proxy = cfg.outbounds.First(o => o.tag == Global.ProxyTag);
- proxy.bind_interface.Should().Be("eth0");
- proxy.detour.Should().BeNullOrEmpty();
+ await proxy.bind_interface.Should().BeEqualTo("eth0");
+ await proxy.detour.Should().BeNull().Or.BeEmpty();
}
- [Fact]
- public void GenerateClientConfigContent_PolicyGroup_ShouldExpandChildrenAndBuildSelector()
+ [Test]
+ public async Task GenerateClientConfigContent_PolicyGroup_ShouldExpandChildrenAndBuildSelector()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -176,17 +169,17 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "selector");
- cfg.outbounds.Should().Contain(o => o.tag == $"{Global.ProxyTag}-auto" && o.type == "urltest");
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "selector");
+ await cfg.outbounds.Should().Contain(o => o.tag == $"{Global.ProxyTag}-auto" && o.type == "urltest");
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
}
- [Fact]
- public void GenerateClientConfigContent_ProxyChain_ShouldBuildDetourChain()
+ [Test]
+ public async Task GenerateClientConfigContent_ProxyChain_ShouldBuildDetourChain()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -203,18 +196,18 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "socks");
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o =>
+ await cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "socks");
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o =>
o.tag == Global.ProxyTag &&
(o.detour ?? string.Empty).StartsWith("chain-proxy-1-", StringComparison.Ordinal));
}
- [Fact]
- public void GenerateClientConfigContent_PolicyGroupWithProxyChain_ShouldBuildCombinedOutbounds()
+ [Test]
+ public async Task GenerateClientConfigContent_PolicyGroupWithProxyChain_ShouldBuildCombinedOutbounds()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -236,18 +229,18 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "selector");
- cfg.outbounds.Should().Contain(o => o.tag == $"{Global.ProxyTag}-auto" && o.type == "urltest");
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "selector");
+ await cfg.outbounds.Should().Contain(o => o.tag == $"{Global.ProxyTag}-auto" && o.type == "urltest");
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
}
- [Fact]
- public void GenerateClientConfigContent_ProxyChainWithPolicyGroup_ShouldBuildClonedChainBranches()
+ [Test]
+ public async Task GenerateClientConfigContent_ProxyChainWithPolicyGroup_ShouldBuildClonedChainBranches()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -269,25 +262,25 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "selector");
- cfg.outbounds.Should().Contain(o => o.tag == $"{Global.ProxyTag}-auto" && o.type == "urltest");
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-2-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.type == "selector");
+ await cfg.outbounds.Should().Contain(o => o.tag == $"{Global.ProxyTag}-auto" && o.type == "urltest");
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-2-", StringComparison.Ordinal));
var proxyCloneCount = cfg.outbounds.Count(o => o.tag.StartsWith("proxy-clone-", StringComparison.Ordinal));
- proxyCloneCount.Should().Be(2);
+ await proxyCloneCount.Should().BeEqualTo(2);
var allCloneDetoursPointToGroupBranches = cfg.outbounds
.Where(o => o.tag.StartsWith("proxy-clone-", StringComparison.Ordinal))
.All(o => (o.detour ?? string.Empty).StartsWith("chain-proxy-1-group-", StringComparison.Ordinal));
- allCloneDetoursPointToGroupBranches.Should().BeTrue();
+ await allCloneDetoursPointToGroupBranches.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_RoutingSplit_DirectAndBlock_ShouldApplyRules()
+ [Test]
+ public async Task GenerateClientConfigContent_RoutingSplit_DirectAndBlock_ShouldApplyRules()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -323,24 +316,24 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var hasDirectRule = cfg.route.rules.Any(r =>
r.domain != null
&& r.domain.Contains("direct.example.com")
&& r.outbound == Global.DirectTag);
- hasDirectRule.Should().BeTrue();
+ await hasDirectRule.Should().BeTrue();
var hasBlockRule = cfg.route.rules.Any(r =>
r.domain != null
&& r.domain.Contains("block.example.com")
&& r.action == "reject");
- hasBlockRule.Should().BeTrue();
+ await hasBlockRule.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_RoutingSplit_ByRemark_ShouldGenerateTargetOutbound()
+ [Test]
+ public async Task GenerateClientConfigContent_RoutingSplit_ByRemark_ShouldGenerateTargetOutbound()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -372,21 +365,21 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var expectedPrefix = $"{routeNode.IndexId}-{Global.ProxyTag}-{routeNode.Remarks}";
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith(expectedPrefix, StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith(expectedPrefix, StringComparison.Ordinal));
var hasRouteRule = cfg.route.rules.Any(r =>
r.domain != null
&& r.domain.Contains("route.example.com")
&& (r.outbound ?? string.Empty).StartsWith(expectedPrefix, StringComparison.Ordinal));
- hasRouteRule.Should().BeTrue();
+ await hasRouteRule.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_DirectExpectedIPs_ShouldApplyGeoipAndCidrToDirectDnsRule()
+ [Test]
+ public async Task GenerateClientConfigContent_DirectExpectedIPs_ShouldApplyGeoipAndCidrToDirectDnsRule()
{
var config = CoreConfigTestFactory.CreateConfigWithDirectExpectedIPs(
ECoreType.sing_box,
@@ -417,7 +410,7 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var hasExpectedRule = cfg.dns.rules?.Any(r =>
@@ -426,11 +419,11 @@ public class CoreConfigSingboxServiceTests
&& r.rule_set?.Contains("geosite-cn") == true
&& r.rule_set?.Contains("geoip-cn") == true) ?? false;
- hasExpectedRule.Should().BeTrue();
+ await hasExpectedRule.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_BootstrapDNS_ShouldConfigurePureIPResolver()
+ [Test]
+ public async Task GenerateClientConfigContent_BootstrapDNS_ShouldConfigurePureIPResolver()
{
var bootstrapDns = "8.8.8.8";
var config = CoreConfigTestFactory.CreateConfigWithBootstrapDNS(ECoreType.sing_box, bootstrapDns);
@@ -441,17 +434,17 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
- config.SimpleDNSItem.BootstrapDNS.Should().Be(bootstrapDns);
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
+ await config.SimpleDNSItem.BootstrapDNS.Should().BeEqualTo(bootstrapDns);
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- var bootstrapServer = cfg.dns.servers?.FirstOrDefault(s => s.tag == Global.SingboxLocalDNSTag);
- bootstrapServer.Should().NotBeNull();
- (bootstrapServer?.server ?? string.Empty).Should().Contain(bootstrapDns);
+ var bootstrapServer = cfg.dns?.servers.FirstOrDefault(s => s.tag == Global.SingboxLocalDNSTag);
+ await bootstrapServer.Should().NotBeNull();
+ await bootstrapServer!.server.Should().Contain(bootstrapDns);
}
- [Fact]
- public void GenerateClientConfigContent_DnsFallback_LastRuleDirect_ShouldUseDirectFinalDns()
+ [Test]
+ public async Task GenerateClientConfigContent_DnsFallback_LastRuleDirect_ShouldUseDirectFinalDns()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
config.SimpleDNSItem.DirectDNS = "1.1.1.1";
@@ -484,14 +477,14 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.dns.final.Should().Be(Global.SingboxDirectDNSTag);
+ await cfg.dns.final.Should().BeEqualTo(Global.SingboxDirectDNSTag);
}
- [Fact]
- public void GenerateClientConfigContent_DirectExpectedIPs_NonMatchingRegion_ShouldNotApplyExpectedRule()
+ [Test]
+ public async Task GenerateClientConfigContent_DirectExpectedIPs_NonMatchingRegion_ShouldNotApplyExpectedRule()
{
var config =
CoreConfigTestFactory.CreateConfigWithDirectExpectedIPs(ECoreType.sing_box, "192.168.0.0/16,geoip:cn");
@@ -521,21 +514,21 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var hasExpectedRule = cfg.dns.rules?.Any(r =>
r.server == Global.SingboxDirectDNSTag
&& r.ip_cidr?.Contains("192.168.0.0/16") == true
&& r.rule_set?.Contains("geoip-cn") == true) ?? false;
- hasExpectedRule.Should().BeFalse();
+ await hasExpectedRule.Should().BeFalse();
}
- [Theory]
- [InlineData("geosite:cn", "geosite-cn")]
- [InlineData("geosite:geolocation-cn", "geosite-geolocation-cn")]
- [InlineData("geosite:tld-cn", "geosite-tld-cn")]
- public void GenerateClientConfigContent_DirectExpectedIPs_RegionVariant_ShouldApplyExpectedRule(string domainTag,
+ [Test]
+ [Arguments("geosite:cn", "geosite-cn")]
+ [Arguments("geosite:geolocation-cn", "geosite-geolocation-cn")]
+ [Arguments("geosite:tld-cn", "geosite-tld-cn")]
+ public async Task GenerateClientConfigContent_DirectExpectedIPs_RegionVariant_ShouldApplyExpectedRule(string domainTag,
string expectedRuleSetTag)
{
var config =
@@ -563,7 +556,7 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var hasExpectedRule = cfg.dns.rules?.Any(r =>
@@ -571,11 +564,11 @@ public class CoreConfigSingboxServiceTests
&& r.ip_cidr?.Contains("192.168.0.0/16") == true
&& r.rule_set?.Contains(expectedRuleSetTag) == true
&& r.rule_set?.Contains("geoip-cn") == true) ?? false;
- hasExpectedRule.Should().BeTrue();
+ await hasExpectedRule.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_Hosts_ShouldPopulateHostsServerAndDomainResolver()
+ [Test]
+ public async Task GenerateClientConfigContent_Hosts_ShouldPopulateHostsServerAndDomainResolver()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
config.SimpleDNSItem.Hosts = "resolver.example 1.1.1.1";
@@ -587,21 +580,21 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var hostsServer = cfg.dns.servers.FirstOrDefault(s => s.tag == Global.SingboxHostsDNSTag);
- hostsServer.Should().NotBeNull();
- hostsServer!.predefined.Should().ContainKey("resolver.example");
- hostsServer.predefined!["resolver.example"].Should().Contain("1.1.1.1");
+ await hostsServer.Should().NotBeNull();
+ await hostsServer!.predefined.Should().ContainKey("resolver.example");
+ await hostsServer.predefined!["resolver.example"].Should().Contain("1.1.1.1");
var directServer = cfg.dns.servers.FirstOrDefault(s => s.tag == Global.SingboxDirectDNSTag);
- directServer.Should().NotBeNull();
- directServer!.domain_resolver.Should().Be(Global.SingboxHostsDNSTag);
+ await directServer.Should().NotBeNull();
+ await directServer!.domain_resolver.Should().BeEqualTo(Global.SingboxHostsDNSTag);
}
- [Fact]
- public void GenerateClientConfigContent_RawDnsEnabled_ShouldUseCustomDnsAndInjectLocalResolver()
+ [Test]
+ public async Task GenerateClientConfigContent_RawDnsEnabled_ShouldUseCustomDnsAndInjectLocalResolver()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -630,22 +623,22 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.dns.servers.Should().Contain(s => s.tag == "remote" && s.type == "udp" && s.server == "8.8.8.8");
- cfg.dns.servers.Should().Contain(s => s.tag == Global.SingboxLocalDNSTag);
- cfg.dns.rules.Should().Contain(r => r.clash_mode == nameof(ERuleMode.Global));
- cfg.dns.rules.Should().Contain(r => r.clash_mode == nameof(ERuleMode.Direct));
+ await cfg.dns.servers.Should().Contain(s => s.tag == "remote" && s.type == "udp" && s.server == "8.8.8.8");
+ await cfg.dns.servers.Should().Contain(s => s.tag == Global.SingboxLocalDNSTag);
+ await cfg.dns.rules.Should().Contain(r => r.clash_mode == nameof(ERuleMode.Global));
+ await cfg.dns.rules.Should().Contain(r => r.clash_mode == nameof(ERuleMode.Direct));
}
- [Fact]
- public void GenerateClientConfigContent_Hysteria2Realm_ShouldEmitHttpsServerUrl()
+ [Test]
+ public async Task GenerateClientConfigContent_Hysteria2Realm_ShouldEmitHttpsServerUrl()
{
var shareLink =
"hysteria2+realm://public@realm.hy2.io/my-realm-id?auth=uuid&stun=turn.cloudflare.com%3A3478&sni=cloudflare.com&pinSHA256=xxx#Realm-Test";
var node = Hysteria2Fmt.ResolveRealm(shareLink, out _);
- node.Should().NotBeNull();
+ await node.Should().NotBeNull();
node!.CoreType = ECoreType.sing_box;
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
@@ -658,22 +651,22 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var proxy = cfg.outbounds.First(o => o.tag == Global.ProxyTag);
- proxy.type.Should().Be("hysteria2");
- proxy.realm.Should().NotBeNull();
- proxy.realm!.server_url.Should().StartWith("https://");
- proxy.realm.server_url.Should().Contain("realm.hy2.io");
- proxy.realm.token.Should().Be("public");
- proxy.realm.realm_id.Should().Be("my-realm-id");
- proxy.realm.stun_servers.Should().Contain("turn.cloudflare.com:3478");
- proxy.server.Should().BeNull();
+ await proxy.type.Should().BeEqualTo("hysteria2");
+ await proxy.realm.Should().NotBeNull();
+ await proxy.realm!.server_url.Should().StartWith("https://");
+ await proxy.realm.server_url.Should().Contain("realm.hy2.io");
+ await proxy.realm.token.Should().BeEqualTo("public");
+ await proxy.realm.realm_id.Should().BeEqualTo("my-realm-id");
+ await proxy.realm.stun_servers.Should().Contain("turn.cloudflare.com:3478");
+ await proxy.server.Should().BeNull();
}
- [Fact]
- public void GenerateClientConfigContent_TunSystemStackWithIpv6_ShouldUsePrefixWithPeerAddress()
+ [Test]
+ public async Task GenerateClientConfigContent_TunSystemStackWithIpv6_ShouldUsePrefixWithPeerAddress()
{
// Regression test for #9820: sing-box fails with "need one more IPv6 address in
// first prefix for system stack" when the TUN inbound uses a /128 IPv6 prefix.
@@ -691,23 +684,24 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var tun = cfg.inbounds.First(i => i.type == "tun");
- tun.address.Should().NotBeNullOrEmpty();
+ await tun.address.Should().NotBeNull();
+ await tun.address.Should().NotBeEmpty();
foreach (var address in tun.address!)
{
var prefixLength = int.Parse(address[(address.LastIndexOf('/') + 1)..]);
var isIpv6 = address.Contains(':');
- prefixLength.Should().BeLessThanOrEqualTo(isIpv6 ? 126 : 30,
+ await prefixLength.Should().BeLessThanOrEqualTo(isIpv6 ? 126 : 30,
$"'{address}' must leave room for the peer address the system stack derives");
}
}
- [Fact]
- public void GenerateClientConfigContent_CustomOutbound_ShouldReplaceWithUserCustomOutboundJson()
+ [Test]
+ public async Task GenerateClientConfigContent_CustomOutbound_ShouldReplaceWithUserCustomOutboundJson()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.sing_box);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -728,17 +722,17 @@ public class CoreConfigSingboxServiceTests
var result = new CoreConfigSingboxService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
- result.Data.Should().NotBeNull();
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
+ await result.Data.Should().NotBeNull();
var cfg = JsonUtils.Deserialize(result.Data!.ToString());
- cfg.Should().NotBeNull();
+ await cfg.Should().NotBeNull();
var proxyOutbound = cfg!.outbounds.FirstOrDefault(o => o.tag == Global.ProxyTag);
- proxyOutbound.Should().NotBeNull();
- proxyOutbound!.type.Should().Be("shadowsocks");
- proxyOutbound.server.Should().Be("1.2.3.4");
- proxyOutbound.server_port.Should().Be(8388);
- proxyOutbound.method.Should().Be("aes-128-gcm");
- proxyOutbound.password.Should().Be("custom_password");
+ await proxyOutbound.Should().NotBeNull();
+ await proxyOutbound!.type.Should().BeEqualTo("shadowsocks");
+ await proxyOutbound.server.Should().BeEqualTo("1.2.3.4");
+ await proxyOutbound.server_port.Should().BeEqualTo(8388);
+ await proxyOutbound.method.Should().BeEqualTo("aes-128-gcm");
+ await proxyOutbound.password.Should().BeEqualTo("custom_password");
}
}
diff --git a/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs b/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs
index bad78c06..ed7154be 100644
--- a/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs
+++ b/v2rayN/ServiceLib.Tests/CoreConfig/V2ray/CoreConfigV2rayServiceTests.cs
@@ -1,16 +1,9 @@
-using AwesomeAssertions;
-using ServiceLib.Common;
-using ServiceLib.Enums;
-using ServiceLib.Models;
-using ServiceLib.Services.CoreConfig;
-using Xunit;
-
namespace ServiceLib.Tests.CoreConfig.V2ray;
public class CoreConfigV2rayServiceTests
{
- [Fact]
- public void GenerateClientConfigContent_ShouldGenerateBasicProxyConfig()
+ [Test]
+ public async Task GenerateClientConfigContent_ShouldGenerateBasicProxyConfig()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -19,17 +12,17 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
- result.Data.Should().NotBeNull();
+ await result.Success.Should().BeTrue();
+ await result.Data.Should().NotBeNull();
var v2rayConfig = JsonUtils.Deserialize(result.Data!.ToString());
- v2rayConfig.Should().NotBeNull();
- v2rayConfig!.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.protocol == "vmess");
- v2rayConfig.inbounds.Should().Contain(i => i.protocol == nameof(EInboundProtocol.mixed));
+ await v2rayConfig.Should().NotBeNull();
+ await v2rayConfig!.outbounds.Should().Contain(o => o.tag == Global.ProxyTag && o.protocol == "vmess");
+ await v2rayConfig.inbounds.Should().Contain(i => i.protocol == nameof(EInboundProtocol.mixed));
}
- [Fact]
- public void GenerateClientConfigContent_HttpOutbound_ShouldEmitHeadersInSettings()
+ [Test]
+ public async Task GenerateClientConfigContent_HttpOutbound_ShouldEmitHeadersInSettings()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -42,27 +35,27 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var outbound = cfg.outbounds.First(o => o.tag == Global.ProxyTag && o.protocol == "http");
- outbound.settings.address?.ToString().Should().Be("proxy.example.com");
- outbound.settings.port.Should().Be(8080);
- outbound.settings.user.Should().Be("user");
- outbound.settings.pass.Should().Be("pass");
- outbound.settings.level.Should().Be(1);
- outbound.settings.headers.Should().NotBeNull();
- var headers = JsonUtils.ParseJson(outbound.settings.headers.ToString());
- headers["User-Agent"]!.GetValue().Should().Be("v2rayN");
- headers["Set-Cookie"]!.AsArray()
+ await outbound.settings.address!.ToString().Should().BeEqualTo("proxy.example.com");
+ await outbound.settings.port.Should().BeEqualTo(8080);
+ await outbound.settings.user.Should().BeEqualTo("user");
+ await outbound.settings.pass.Should().BeEqualTo("pass");
+ await outbound.settings.level.Should().BeEqualTo(1);
+ await outbound.settings.headers.Should().NotBeNull();
+ var headers = JsonUtils.ParseJson(outbound.settings.headers!.ToString());
+ await headers["User-Agent"]!.GetValue().Should().BeEqualTo("v2rayN");
+ await headers["Set-Cookie"]!.AsArray()
.Select(item => item!.GetValue())
- .Should().Equal("a=1", "b=2");
- outbound.settings.servers.Should().BeNull();
- outbound.settings.vnext.Should().BeNull();
+ .Should().BeEquivalentTo(["a=1", "b=2"]);
+ await outbound.settings.servers.Should().BeNull();
+ await outbound.settings.vnext.Should().BeNull();
}
- [Fact]
- public void GenerateClientConfigContent_PolicyGroup_ShouldExpandChildrenAndBuildBalancer()
+ [Test]
+ public async Task GenerateClientConfigContent_PolicyGroup_ShouldExpandChildrenAndBuildBalancer()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -79,17 +72,17 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
- cfg.routing.balancers.Should().NotBeNull();
- cfg.routing.balancers!.Should().Contain(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix);
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
+ await cfg.routing.balancers.Should().NotBeNull();
+ await cfg.routing.balancers!.Should().Contain(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix);
}
- [Fact]
- public void GenerateClientConfigContent_ProxyChain_ShouldBuildDialerProxyChain()
+ [Test]
+ public async Task GenerateClientConfigContent_ProxyChain_ShouldBuildDialerProxyChain()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -105,21 +98,21 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
var hasDialerChain = cfg.outbounds.Any(o =>
o.tag == Global.ProxyTag
&& o.streamSettings is not null
&& o.streamSettings.sockopt is not null
&& (o.streamSettings.sockopt.dialerProxy ?? string.Empty).StartsWith("chain-proxy-1-",
StringComparison.Ordinal));
- hasDialerChain.Should().BeTrue();
+ await hasDialerChain.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_PolicyGroupWithProxyChain_ShouldBuildCombinedOutbounds()
+ [Test]
+ public async Task GenerateClientConfigContent_PolicyGroupWithProxyChain_ShouldBuildCombinedOutbounds()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -140,18 +133,18 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
- cfg.routing.balancers.Should().NotBeNull();
- cfg.routing.balancers!.Should().Contain(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix);
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("proxy-2-", StringComparison.Ordinal));
+ await cfg.routing.balancers.Should().NotBeNull();
+ await cfg.routing.balancers!.Should().Contain(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix);
}
- [Fact]
- public void GenerateClientConfigContent_ProxyChainWithPolicyGroup_ShouldBuildClonedChainBranches()
+ [Test]
+ public async Task GenerateClientConfigContent_ProxyChainWithPolicyGroup_ShouldBuildClonedChainBranches()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -173,27 +166,27 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-1-", StringComparison.Ordinal));
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-2-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-1-", StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith("chain-proxy-1-group-2-", StringComparison.Ordinal));
var proxyCloneCount = cfg.outbounds.Count(o => o.tag.StartsWith("proxy-clone-", StringComparison.Ordinal));
- proxyCloneCount.Should().Be(2);
+ await proxyCloneCount.Should().BeEqualTo(2);
var allCloneDialersPointToGroupBranches = cfg.outbounds
.Where(o => o.tag.StartsWith("proxy-clone-", StringComparison.Ordinal))
.All(o => (o.streamSettings?.sockopt?.dialerProxy ?? string.Empty).StartsWith("chain-proxy-1-group-",
StringComparison.Ordinal));
- allCloneDialersPointToGroupBranches.Should().BeTrue();
+ await allCloneDialersPointToGroupBranches.Should().BeTrue();
- cfg.routing.balancers.Should().NotBeNull();
- cfg.routing.balancers!.Should().Contain(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix);
+ await cfg.routing.balancers.Should().NotBeNull();
+ await cfg.routing.balancers!.Should().Contain(b => b.tag == Global.ProxyTag + Global.BalancerTagSuffix);
}
- [Fact]
- public void GenerateClientConfigContent_RoutingSplit_DirectAndBlock_ShouldApplyRules()
+ [Test]
+ public async Task GenerateClientConfigContent_RoutingSplit_DirectAndBlock_ShouldApplyRules()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -229,24 +222,24 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var hasDirectRule = cfg.routing.rules.Any(r =>
r.domain != null
&& r.domain.Contains("full:direct.example.com")
&& r.outboundTag == Global.DirectTag);
- hasDirectRule.Should().BeTrue();
+ await hasDirectRule.Should().BeTrue();
var hasBlockRule = cfg.routing.rules.Any(r =>
r.domain != null
&& r.domain.Contains("full:block.example.com")
&& r.outboundTag == Global.BlockTag);
- hasBlockRule.Should().BeTrue();
+ await hasBlockRule.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_RoutingSplit_ByRemark_ShouldGenerateTargetOutbound()
+ [Test]
+ public async Task GenerateClientConfigContent_RoutingSplit_ByRemark_ShouldGenerateTargetOutbound()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -278,20 +271,20 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var expectedPrefix = $"{routeNode.IndexId}-{Global.ProxyTag}-{routeNode.Remarks}";
- cfg.outbounds.Should().Contain(o => o.tag.StartsWith(expectedPrefix, StringComparison.Ordinal));
+ await cfg.outbounds.Should().Contain(o => o.tag.StartsWith(expectedPrefix, StringComparison.Ordinal));
var hasRouteRule = cfg.routing.rules.Any(r =>
r.domain != null
&& r.domain.Contains("full:route.example.com")
&& (r.outboundTag ?? string.Empty).StartsWith(expectedPrefix, StringComparison.Ordinal));
- hasRouteRule.Should().BeTrue();
+ await hasRouteRule.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_DirectExpectedIPs_ShouldApplyExpectedIPsToDirectDnsServer()
+ [Test]
+ public async Task GenerateClientConfigContent_DirectExpectedIPs_ShouldApplyExpectedIPsToDirectDnsServer()
{
var config = CoreConfigTestFactory.CreateConfigWithDirectExpectedIPs(ECoreType.Xray, "192.168.0.0/16,geoip:cn");
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -320,7 +313,7 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
@@ -335,11 +328,11 @@ public class CoreConfigV2rayServiceTests
&& s.domains?.Contains("geosite:cn") == true
&& s.expectedIPs?.Contains("192.168.0.0/16") == true
&& s.expectedIPs?.Contains("geoip:cn") == true);
- hasExpectedServer.Should().BeTrue();
+ await hasExpectedServer.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_BootstrapDNS_ShouldApplyToDnsServerDomains()
+ [Test]
+ public async Task GenerateClientConfigContent_BootstrapDNS_ShouldApplyToDnsServerDomains()
{
var bootstrapDns = "8.8.8.8";
var config = CoreConfigTestFactory.CreateConfigWithBootstrapDNS(ECoreType.Xray, bootstrapDns);
@@ -352,7 +345,7 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
@@ -366,11 +359,11 @@ public class CoreConfigV2rayServiceTests
s.address == bootstrapDns
&& s.domains?.Contains("full:dns-direct.example") == true
&& s.domains?.Contains("full:dns-remote.example") == true);
- hasBootstrapServer.Should().BeTrue();
+ await hasBootstrapServer.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_DnsFallback_LastRuleDirect_ShouldUseDirectDnsServers()
+ [Test]
+ public async Task GenerateClientConfigContent_DnsFallback_LastRuleDirect_ShouldUseDirectDnsServers()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
config.SimpleDNSItem.DirectDNS = "1.1.1.1";
@@ -403,7 +396,7 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
var dnsServers = dns.servers
@@ -415,14 +408,14 @@ public class CoreConfigV2rayServiceTests
var hasDirectFallback = dnsServers.Any(s =>
(s.tag ?? string.Empty).StartsWith(Global.DirectDnsTag, StringComparison.Ordinal)
&& s.address == "1.1.1.1");
- hasDirectFallback.Should().BeTrue();
+ await hasDirectFallback.Should().BeTrue();
var hasRemoteFallback = dnsServers.Any(s => s.address == "9.9.9.9");
- hasRemoteFallback.Should().BeFalse();
+ await hasRemoteFallback.Should().BeFalse();
}
- [Fact]
- public void GenerateClientConfigContent_DirectExpectedIPs_NonMatchingRegion_ShouldNotApplyExpectedIPs()
+ [Test]
+ public async Task GenerateClientConfigContent_DirectExpectedIPs_NonMatchingRegion_ShouldNotApplyExpectedIPs()
{
var config = CoreConfigTestFactory.CreateConfigWithDirectExpectedIPs(ECoreType.Xray, "192.168.0.0/16,geoip:cn");
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -451,7 +444,7 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
var dnsServers = dns.servers
@@ -463,14 +456,14 @@ public class CoreConfigV2rayServiceTests
var hasExpectedIPs = dnsServers.Any(s =>
s.expectedIPs?.Contains("192.168.0.0/16") == true
|| s.expectedIPs?.Contains("geoip:cn") == true);
- hasExpectedIPs.Should().BeFalse();
+ await hasExpectedIPs.Should().BeFalse();
}
- [Theory]
- [InlineData("geosite:cn")]
- [InlineData("geosite:geolocation-cn")]
- [InlineData("geosite:tld-cn")]
- public void GenerateClientConfigContent_DirectExpectedIPs_RegionVariant_ShouldApplyExpectedIPs(string domainTag)
+ [Test]
+ [Arguments("geosite:cn")]
+ [Arguments("geosite:geolocation-cn")]
+ [Arguments("geosite:tld-cn")]
+ public async Task GenerateClientConfigContent_DirectExpectedIPs_RegionVariant_ShouldApplyExpectedIPs(string domainTag)
{
var config = CoreConfigTestFactory.CreateConfigWithDirectExpectedIPs(ECoreType.Xray, "192.168.0.0/16,geoip:cn");
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -496,7 +489,7 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
var dnsServers = dns.servers
@@ -510,11 +503,11 @@ public class CoreConfigV2rayServiceTests
&& s.domains?.Contains(domainTag) == true
&& s.expectedIPs?.Contains("192.168.0.0/16") == true
&& s.expectedIPs?.Contains("geoip:cn") == true);
- hasExpectedServer.Should().BeTrue();
+ await hasExpectedServer.Should().BeTrue();
}
- [Fact]
- public void GenerateClientConfigContent_Hosts_ShouldPopulateDnsHosts()
+ [Test]
+ public async Task GenerateClientConfigContent_Hosts_ShouldPopulateDnsHosts()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
config.SimpleDNSItem.Hosts = "resolver.example 1.1.1.1";
@@ -525,17 +518,17 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
- dns.hosts.Should().NotBeNull();
- dns.hosts!.Should().ContainKey("resolver.example");
- JsonUtils.Serialize(dns.hosts!["resolver.example"]).Should().Contain("1.1.1.1");
+ await dns.hosts.Should().NotBeNull();
+ await dns.hosts!.Should().ContainKey("resolver.example");
+ await JsonUtils.Serialize(dns.hosts!["resolver.example"]).Should().Contain("1.1.1.1");
}
- [Fact]
- public void GenerateClientConfigContent_RawDnsEnabled_ShouldUseCustomDnsConfig()
+ [Test]
+ public async Task GenerateClientConfigContent_RawDnsEnabled_ShouldUseCustomDnsConfig()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -556,24 +549,24 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var dns = JsonUtils.Deserialize(JsonUtils.Serialize(cfg.dns))!;
- JsonUtils.Serialize(dns.servers).Should().Contain("8.8.8.8");
- dns.hosts.Should().NotBeNull();
- dns.hosts!.Should().ContainKey("raw.example");
- JsonUtils.Serialize(dns.hosts!["raw.example"]).Should().Contain("1.1.1.1");
+ await JsonUtils.Serialize(dns.servers).Should().Contain("8.8.8.8");
+ await dns.hosts.Should().NotBeNull();
+ await dns.hosts!.Should().ContainKey("raw.example");
+ await JsonUtils.Serialize(dns.hosts!["raw.example"]).Should().Contain("1.1.1.1");
var directOutbound = cfg.outbounds.FirstOrDefault(o => o.tag == Global.DirectTag && o.protocol == "freedom");
- directOutbound.Should().NotBeNull();
- directOutbound!.streamSettings.sockopt!.domainStrategy.Should().Be("UseIPv4");
+ await directOutbound.Should().NotBeNull();
+ await directOutbound!.streamSettings.sockopt!.domainStrategy.Should().BeEqualTo("UseIPv4");
}
- [Theory]
- [InlineData(false)]
- [InlineData(true)]
- public void GenerateClientConfigContent_Tun_ShouldRouteIPv6IntoTunnel(bool enableIPv6Address)
+ [Test]
+ [Arguments(false)]
+ [Arguments(true)]
+ public async Task GenerateClientConfigContent_Tun_ShouldRouteIPv6IntoTunnel(bool enableIPv6Address)
{
var config = CoreConfigTestFactory.CreateConfigWithTun(ECoreType.Xray, enableIPv6Address);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -583,20 +576,20 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var tunInbound = cfg.inbounds.FirstOrDefault(i => i.protocol == "tun");
- tunInbound.Should().NotBeNull();
- tunInbound!.settings.autoSystemRoutingTable.Should().Contain("0.0.0.0/0");
- tunInbound.settings.autoSystemRoutingTable.Should().Contain("::/0");
+ await tunInbound.Should().NotBeNull();
+ await tunInbound!.settings.autoSystemRoutingTable.Should().Contain("0.0.0.0/0");
+ await tunInbound.settings.autoSystemRoutingTable.Should().Contain("::/0");
// EnableIPv6Address governs the interface address only, never the routing table.
- tunInbound.settings.gateway.Should().HaveCount(enableIPv6Address ? 2 : 1);
+ await tunInbound.settings.gateway.Should().HaveCount(enableIPv6Address ? 2 : 1);
}
- [Fact]
- public void GenerateClientConfigContent_TunRouteExcludeAddress_ShouldIncludeIPv6Ranges()
+ [Test]
+ public async Task GenerateClientConfigContent_TunRouteExcludeAddress_ShouldIncludeIPv6Ranges()
{
var config = CoreConfigTestFactory.CreateConfigWithTunRouteExcludeAddress(ECoreType.Xray);
config.TunModeItem.EnableIPv6Address = false;
@@ -607,16 +600,16 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var tunInbound = cfg.inbounds.FirstOrDefault(i => i.protocol == "tun");
- tunInbound.Should().NotBeNull();
- tunInbound!.settings.autoSystemRoutingTable.Should().Contain(x => x.Contains(':'));
+ await tunInbound.Should().NotBeNull();
+ await tunInbound!.settings.autoSystemRoutingTable.Should().Contain(x => x.Contains(':'));
}
- [Fact]
- public void GenerateClientConfigContent_TunRouteExcludeAddress()
+ [Test]
+ public async Task GenerateClientConfigContent_TunRouteExcludeAddress()
{
var config = CoreConfigTestFactory.CreateConfigWithTunRouteExcludeAddress(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -626,20 +619,20 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue();
+ await result.Success.Should().BeTrue();
var cfg = JsonUtils.Deserialize(result.Data!.ToString())!;
var tunInbound = cfg.inbounds.FirstOrDefault(i => i.protocol == "tun");
- tunInbound.Should().NotBeNull();
+ await tunInbound.Should().NotBeNull();
- tunInbound!.settings.autoSystemRoutingTable.Should().NotContain("0.0.0.0/0");
- tunInbound!.settings.autoSystemRoutingTable.Should().Contain("10.0.0.0/32");
- tunInbound!.settings.autoSystemRoutingTable.Should().Contain("10.0.0.2/31");
+ await tunInbound!.settings.autoSystemRoutingTable.Should().NotContain("0.0.0.0/0");
+ await tunInbound!.settings.autoSystemRoutingTable.Should().Contain("10.0.0.0/32");
+ await tunInbound!.settings.autoSystemRoutingTable.Should().Contain("10.0.0.2/31");
}
- [Fact]
- public void GenerateClientConfigContent_CustomOutbound_ShouldReplaceWithUserCustomOutboundJson()
+ [Test]
+ public async Task GenerateClientConfigContent_CustomOutbound_ShouldReplaceWithUserCustomOutboundJson()
{
var config = CoreConfigTestFactory.CreateConfig(ECoreType.Xray);
CoreConfigTestFactory.BindAppManagerConfig(config);
@@ -666,14 +659,14 @@ public class CoreConfigV2rayServiceTests
var result = new CoreConfigV2rayService(context).GenerateClientConfigContent();
- result.Success.Should().BeTrue($"ret msg: {result.Msg}");
- result.Data.Should().NotBeNull();
+ await result.Success.Should().BeTrue().Because($"ret msg: {result.Msg}");
+ await result.Data.Should().NotBeNull();
var cfg = JsonUtils.Deserialize(result.Data!.ToString());
- cfg.Should().NotBeNull();
+ await cfg.Should().NotBeNull();
var proxyOutbound = cfg!.outbounds.FirstOrDefault(o => o.tag == Global.ProxyTag);
- proxyOutbound.Should().NotBeNull();
- proxyOutbound!.protocol.Should().Be("shadowsocks");
- proxyOutbound.settings.servers.Should().NotBeNull();
+ await proxyOutbound.Should().NotBeNull();
+ await proxyOutbound!.protocol.Should().BeEqualTo("shadowsocks");
+ await proxyOutbound.settings.servers.Should().NotBeNull();
}
}
diff --git a/v2rayN/ServiceLib.Tests/Fmt/FmtHandlerTests.cs b/v2rayN/ServiceLib.Tests/Fmt/FmtHandlerTests.cs
index 143fa3e5..bca21685 100644
--- a/v2rayN/ServiceLib.Tests/Fmt/FmtHandlerTests.cs
+++ b/v2rayN/ServiceLib.Tests/Fmt/FmtHandlerTests.cs
@@ -1,103 +1,99 @@
-using AwesomeAssertions;
-using ServiceLib.Enums;
-using ServiceLib.Handler.Fmt;
-using ServiceLib.Models;
-using Xunit;
-
namespace ServiceLib.Tests.Fmt;
public class FmtHandlerTests
{
- [Fact]
- public void GetShareUriAndResolveConfig_Vmess_ShouldRoundTripBasicFields()
+ [Test]
+ public async Task GetShareUriAndResolveConfig_Vmess_ShouldRoundTripBasicFields()
{
var source = CreateVmessProfile();
- var resolved = ExportThenImport(source);
+ var resolved = await ExportThenImport(source);
- resolved.ConfigType.Should().Be(EConfigType.VMess);
- resolved.Remarks.Should().Be(source.Remarks);
- resolved.Address.Should().Be(source.Address);
- resolved.Port.Should().Be(source.Port);
- resolved.Password.Should().Be(source.Password);
- resolved.GetProtocolExtra().AlterId.Should().Be(source.GetProtocolExtra().AlterId);
+ await resolved.ConfigType.Should().BeEqualTo(EConfigType.VMess);
+ await resolved.Remarks.Should().BeEqualTo(source.Remarks);
+ await resolved.Address.Should().BeEqualTo(source.Address);
+ await resolved.Port.Should().BeEqualTo(source.Port);
+ await resolved.Password.Should().BeEqualTo(source.Password);
+ await resolved.GetProtocolExtra().AlterId.Should().BeEqualTo(source.GetProtocolExtra().AlterId);
}
- [Fact]
- public void GetShareUriAndResolveConfig_Vless_ShouldRoundTripBasicFields()
+ [Test]
+ public async Task GetShareUriAndResolveConfig_Vless_ShouldRoundTripBasicFields()
{
var source = CreateVlessProfile();
- var resolved = ExportThenImport(source);
+ var resolved = await ExportThenImport(source);
- resolved.ConfigType.Should().Be(EConfigType.VLESS);
- resolved.Remarks.Should().Be(source.Remarks);
- resolved.Address.Should().Be(source.Address);
- resolved.Port.Should().Be(source.Port);
- resolved.Password.Should().Be(source.Password);
- resolved.GetProtocolExtra().VlessEncryption.Should().Be(Global.None);
+ await resolved.ConfigType.Should().BeEqualTo(EConfigType.VLESS);
+ await resolved.Remarks.Should().BeEqualTo(source.Remarks);
+ await resolved.Address.Should().BeEqualTo(source.Address);
+ await resolved.Port.Should().BeEqualTo(source.Port);
+ await resolved.Password.Should().BeEqualTo(source.Password);
+ await resolved.GetProtocolExtra().VlessEncryption.Should().BeEqualTo(Global.None);
}
- [Fact]
- public void GetShareUriAndResolveConfig_Shadowsocks_ShouldRoundTripBasicFields()
+ [Test]
+ public async Task GetShareUriAndResolveConfig_Shadowsocks_ShouldRoundTripBasicFields()
{
var source = CreateShadowsocksProfile();
- var resolved = ExportThenImport(source);
+ var resolved = await ExportThenImport(source);
- resolved.ConfigType.Should().Be(EConfigType.Shadowsocks);
- resolved.Remarks.Should().Be(source.Remarks);
- resolved.Address.Should().Be(source.Address);
- resolved.Port.Should().Be(source.Port);
- resolved.Password.Should().Be(source.Password);
- resolved.GetProtocolExtra().SsMethod.Should().Be(source.GetProtocolExtra().SsMethod);
+ await resolved.ConfigType.Should().BeEqualTo(EConfigType.Shadowsocks);
+ await resolved.Remarks.Should().BeEqualTo(source.Remarks);
+ await resolved.Address.Should().BeEqualTo(source.Address);
+ await resolved.Port.Should().BeEqualTo(source.Port);
+ await resolved.Password.Should().BeEqualTo(source.Password);
+ await resolved.GetProtocolExtra().SsMethod.Should().BeEqualTo(source.GetProtocolExtra().SsMethod);
}
- [Fact]
- public void GetShareUriAndResolveConfig_Socks_ShouldRoundTripBasicFields()
+ [Test]
+ public async Task GetShareUriAndResolveConfig_Socks_ShouldRoundTripBasicFields()
{
var source = CreateSocksProfile();
- var resolved = ExportThenImport(source);
+ var resolved = await ExportThenImport(source);
- resolved.ConfigType.Should().Be(EConfigType.SOCKS);
- resolved.Remarks.Should().Be(source.Remarks);
- resolved.Address.Should().Be(source.Address);
- resolved.Port.Should().Be(source.Port);
- resolved.Username.Should().Be(source.Username);
- resolved.Password.Should().Be(source.Password);
+ await resolved.ConfigType.Should().BeEqualTo(EConfigType.SOCKS);
+ await resolved.Remarks.Should().BeEqualTo(source.Remarks);
+ await resolved.Address.Should().BeEqualTo(source.Address);
+ await resolved.Port.Should().BeEqualTo(source.Port);
+ await resolved.Username.Should().BeEqualTo(source.Username);
+ await resolved.Password.Should().BeEqualTo(source.Password);
}
- [Fact]
- public void ResolveConfig_UnsupportedProtocol_ShouldReturnNull()
+ [Test]
+ public async Task ResolveConfig_UnsupportedProtocol_ShouldReturnNull()
{
var resolved = FmtHandler.ResolveConfig("not-a-share-uri", out var msg);
- resolved.Should().BeNull();
- msg.Should().NotBeNullOrWhiteSpace();
+ await resolved.Should().BeNull();
+ await msg.Should().NotBeNull();
+ await msg.Should().NotBeEmpty();
}
- [Fact]
- public void GetShareUri_UnsupportedConfigType_ShouldReturnNull()
+ [Test]
+ public async Task GetShareUri_UnsupportedConfigType_ShouldReturnNull()
{
var item = new ProfileItem { ConfigType = EConfigType.PolicyGroup, Remarks = "group", };
var uri = FmtHandler.GetShareUri(item);
- uri.Should().BeNull();
+ await uri.Should().BeNull();
}
- private static ProfileItem ExportThenImport(ProfileItem source)
+ private static async Task ExportThenImport(ProfileItem source)
{
var uri = FmtHandler.GetShareUri(source);
- uri.Should().NotBeNullOrWhiteSpace();
- uri!.StartsWith(Global.ProtocolShares[source.ConfigType], StringComparison.OrdinalIgnoreCase).Should()
+ await uri.Should().NotBeNull();
+ await uri.Should().NotBeEmpty();
+ await uri!.StartsWith(Global.ProtocolShares[source.ConfigType], StringComparison.OrdinalIgnoreCase).Should()
.BeTrue();
var resolved = FmtHandler.ResolveConfig(uri, out var msg);
- resolved.Should().NotBeNull($"uri: {uri}, msg: {msg}");
+ await resolved.Should().NotBeNull().Because($"uri: {uri}, msg: {msg}");
return resolved!;
}
diff --git a/v2rayN/ServiceLib.Tests/Fmt/HyRealmTests.cs b/v2rayN/ServiceLib.Tests/Fmt/HyRealmTests.cs
index 3cce2ed5..42eb5e86 100644
--- a/v2rayN/ServiceLib.Tests/Fmt/HyRealmTests.cs
+++ b/v2rayN/ServiceLib.Tests/Fmt/HyRealmTests.cs
@@ -1,32 +1,27 @@
-using AwesomeAssertions;
-using ServiceLib.Handler.Fmt;
-using ServiceLib.Models.Dto;
-using Xunit;
-
namespace ServiceLib.Tests.Fmt;
public class HyRealmTests
{
- [Fact]
- public void TryParse_ShouldParseValidRealm()
+ [Test]
+ public async Task TryParse_ShouldParseValidRealm()
{
var str = "realm://public@realm.hy2.io/57f9be7c-2810-4f5b-8cb9-260bc84d6c90?stun=example.stun:3478&stun=example2.stun:3478";
var result = HyRealm.TryParse(str, out var realm);
- result.Should().BeTrue();
- realm.Should().NotBeNull();
+ await result.Should().BeTrue();
+ await realm.Should().NotBeNull();
- realm.IsHttp.Should().BeFalse();
- realm.Token.Should().Be("public");
- realm.RendezvousHost.Should().Be("realm.hy2.io");
- realm.RendezvousPort.Should().Be(443);
- realm.RealmName.Should().Be("57f9be7c-2810-4f5b-8cb9-260bc84d6c90");
- realm.StunList.Should().HaveCount(2);
- realm.StunList.Should().Contain("example.stun:3478");
- realm.StunList.Should().Contain("example2.stun:3478");
+ await realm.IsHttp.Should().BeFalse();
+ await realm.Token.Should().BeEqualTo("public");
+ await realm.RendezvousHost.Should().BeEqualTo("realm.hy2.io");
+ await realm.RendezvousPort.Should().BeEqualTo(443);
+ await realm.RealmName.Should().BeEqualTo("57f9be7c-2810-4f5b-8cb9-260bc84d6c90");
+ await realm.StunList.Should().HaveCount(2);
+ await realm.StunList.Should().Contain("example.stun:3478");
+ await realm.StunList.Should().Contain("example2.stun:3478");
}
- [Fact]
- public void ToUri_ShouldGenerateValidUri()
+ [Test]
+ public async Task ToUri_ShouldGenerateValidUri()
{
var realm = new HyRealm(
IsHttp: false,
@@ -37,32 +32,32 @@ public class HyRealmTests
StunList: ["example.stun:3478", "example2.stun:3478"]
);
var uri = realm.ToUri();
- uri.Should().Contain("realm://public@realm.hy2.io");
- uri.Should().Contain("/57f9be7c-2810-4f5b-8cb9-260bc84d6c90");
- uri.Should().Contain("stun=example.stun:3478");
- uri.Should().Contain("stun=example2.stun:3478");
+ await uri.Should().Contain("realm://public@realm.hy2.io");
+ await uri.Should().Contain("/57f9be7c-2810-4f5b-8cb9-260bc84d6c90");
+ await uri.Should().Contain("stun=example.stun:3478");
+ await uri.Should().Contain("stun=example2.stun:3478");
}
- [Fact]
- public void GetShareUriAndResolveConfig_Hy2Realm_ShouldRoundTripBasicFields()
+ [Test]
+ public async Task GetShareUriAndResolveConfig_Hy2Realm_ShouldRoundTripBasicFields()
{
var str = "hysteria2+realm://mytoken@rendezvous.example.com/my-cabin-1f3a8c2e9b?auth=your_password&insecure=1&pinSHA256=deadbeef#remark";
var resolved = Hysteria2Fmt.ResolveRealm(str, out var msg);
- resolved.Should().NotBeNull();
- resolved.Password.Should().Be("your_password");
+ await resolved.Should().NotBeNull();
+ await resolved.Password.Should().BeEqualTo("your_password");
var result = HyRealm.TryParse(resolved.GetProtocolExtra().Hy2RealmUrl, out var realm);
- result.Should().BeTrue();
- realm.Should().NotBeNull();
- realm.Token.Should().Be("mytoken");
+ await result.Should().BeTrue();
+ await realm.Should().NotBeNull();
+ await realm.Token.Should().BeEqualTo("mytoken");
// To uri
var uri = Hysteria2Fmt.ToUri(resolved);
- uri.Should().Contain("hysteria2+realm://mytoken@rendezvous.example.com");
- uri.Should().EndWith("#remark");
+ await uri.Should().Contain("hysteria2+realm://mytoken@rendezvous.example.com");
+ await uri.Should().EndWith("#remark");
}
- [Fact]
- public void ToServerUrl_ShouldIncludeSchemeForSingbox()
+ [Test]
+ public async Task ToServerUrl_ShouldIncludeSchemeForSingbox()
{
var realm = new HyRealm(
IsHttp: false,
@@ -73,19 +68,19 @@ public class HyRealmTests
StunList: ["turn.cloudflare.com:3478"]
);
- realm.ToServerUrl().Should().Be("https://realm.hy2.io:443");
+ await realm.ToServerUrl().Should().BeEqualTo("https://realm.hy2.io:443");
}
- [Fact]
- public void ResolveRealm_Issue9635_ShouldProduceHttpsServerUrl()
+ [Test]
+ public async Task ResolveRealm_Issue9635_ShouldProduceHttpsServerUrl()
{
var str = "hysteria2+realm://public@realm.hy2.io/my-realm-id?auth=uuid&stun=turn.cloudflare.com%3A3478&sni=cloudflare.com&pinSHA256=xxx#Realm-Test";
var resolved = Hysteria2Fmt.ResolveRealm(str, out _);
- resolved.Should().NotBeNull();
+ await resolved.Should().NotBeNull();
- HyRealm.TryParse(resolved!.GetProtocolExtra().Hy2RealmUrl, out var realm).Should().BeTrue();
- realm!.ToServerUrl().Should().StartWith("https://");
- realm.ToServerUrl().Should().Contain("realm.hy2.io");
- realm.StunList.Should().Contain("turn.cloudflare.com:3478");
+ await HyRealm.TryParse(resolved!.GetProtocolExtra().Hy2RealmUrl, out var realm).Should().BeTrue();
+ await realm!.ToServerUrl().Should().StartWith("https://");
+ await realm.ToServerUrl().Should().Contain("realm.hy2.io");
+ await realm.StunList.Should().Contain("turn.cloudflare.com:3478");
}
}
diff --git a/v2rayN/ServiceLib.Tests/Fmt/InnerFmtTests.cs b/v2rayN/ServiceLib.Tests/Fmt/InnerFmtTests.cs
index 91df67f4..962fdd82 100644
--- a/v2rayN/ServiceLib.Tests/Fmt/InnerFmtTests.cs
+++ b/v2rayN/ServiceLib.Tests/Fmt/InnerFmtTests.cs
@@ -1,15 +1,11 @@
-using AwesomeAssertions;
-using ServiceLib.Enums;
-using ServiceLib.Handler.Fmt;
using ServiceLib.Tests.CoreConfig;
-using Xunit;
namespace ServiceLib.Tests.Fmt;
public class InnerFmtTests
{
- [Fact]
- public void ToUriAndResolve_ShouldRoundTripPolicyGroupReferences()
+ [Test]
+ public async Task ToUriAndResolve_ShouldRoundTripPolicyGroupReferences()
{
var childA = CoreConfigTestFactory.CreateSocksNode(ECoreType.Xray, "child-a", "child-a");
var childB = CoreConfigTestFactory.CreateVmessNode(ECoreType.Xray, "child-b", "child-b");
@@ -19,19 +15,20 @@ public class InnerFmtTests
var uri = InnerFmt.ToUri([group, childA, childB]);
- uri.Should().NotBeNullOrWhiteSpace();
+ await uri.Should().NotBeNull();
+ await uri.Should().NotBeEmpty();
var resolved = InnerFmt.Resolve(uri!, "sub-123");
- resolved.Should().NotBeNull();
- resolved.Should().HaveCount(3);
+ await resolved.Should().NotBeNull();
+ await resolved.Should().HaveCount(3);
var resolvedGroup = resolved!.Single(x => x.Remarks == group.Remarks);
var resolvedChildA = resolved.Single(x => x.Remarks == childA.Remarks);
var resolvedChildB = resolved.Single(x => x.Remarks == childB.Remarks);
- resolvedGroup.ConfigType.Should().Be(EConfigType.PolicyGroup);
- resolvedGroup.GetProtocolExtra().SubChildItems.Should().Be("sub-123");
- resolvedGroup.GetProtocolExtra().ChildItems.Should().Be($"{resolvedChildA.IndexId},{resolvedChildB.IndexId}");
+ await resolvedGroup.ConfigType.Should().BeEqualTo(EConfigType.PolicyGroup);
+ await resolvedGroup.GetProtocolExtra().SubChildItems.Should().BeEqualTo("sub-123");
+ await resolvedGroup.GetProtocolExtra().ChildItems.Should().BeEqualTo($"{resolvedChildA.IndexId},{resolvedChildB.IndexId}");
}
}
diff --git a/v2rayN/ServiceLib.Tests/Fmt/WireguardFmtTests.cs b/v2rayN/ServiceLib.Tests/Fmt/WireguardFmtTests.cs
index 717fa1bc..8f156b47 100644
--- a/v2rayN/ServiceLib.Tests/Fmt/WireguardFmtTests.cs
+++ b/v2rayN/ServiceLib.Tests/Fmt/WireguardFmtTests.cs
@@ -1,13 +1,9 @@
-using AwesomeAssertions;
-using ServiceLib.Handler.Fmt;
-using Xunit;
-
namespace ServiceLib.Tests.Fmt;
public class WireguardFmtTests
{
- [Fact]
- public void ResolveConfig_ShouldParsePeersAndIgnoreInlineComments()
+ [Test]
+ public async Task ResolveConfig_ShouldParsePeersAndIgnoreInlineComments()
{
const string config =
"""
@@ -29,19 +25,19 @@ public class WireguardFmtTests
var resolved = WireguardFmt.ResolveConfig(config);
- resolved.Should().NotBeNull();
- resolved.Should().HaveCount(2);
+ await resolved.Should().NotBeNull();
+ await resolved.Should().HaveCount(2);
var first = resolved![0];
- first.Address.Should().Be("2001:db8::1");
- first.Port.Should().Be(51820);
- first.Password.Should().Be("interface-private-key");
- first.GetProtocolExtra().WgReserved.Should().Be("1, 2, 3");
- first.GetProtocolExtra().WgInterfaceAddress.Should().Be("10.0.0.2/32, fd00::2/128");
- first.GetProtocolExtra().WgMtu.Should().Be(1420);
+ await first.Address.Should().BeEqualTo("2001:db8::1");
+ await first.Port.Should().BeEqualTo(51820);
+ await first.Password.Should().BeEqualTo("interface-private-key");
+ await first.GetProtocolExtra().WgReserved.Should().BeEqualTo("1, 2, 3");
+ await first.GetProtocolExtra().WgInterfaceAddress.Should().BeEqualTo("10.0.0.2/32, fd00::2/128");
+ await first.GetProtocolExtra().WgMtu.Should().BeEqualTo(1420);
var second = resolved[1];
- second.Address.Should().Be("example.com");
- second.Port.Should().Be(12345);
+ await second.Address.Should().BeEqualTo("example.com");
+ await second.Port.Should().BeEqualTo(12345);
}
}
diff --git a/v2rayN/ServiceLib.Tests/Manager/CoreManagerTests.cs b/v2rayN/ServiceLib.Tests/Manager/CoreManagerTests.cs
index d4135758..0c7f0ebc 100644
--- a/v2rayN/ServiceLib.Tests/Manager/CoreManagerTests.cs
+++ b/v2rayN/ServiceLib.Tests/Manager/CoreManagerTests.cs
@@ -1,44 +1,39 @@
-using AwesomeAssertions;
-using ServiceLib.Enums;
-using ServiceLib.Manager;
-using Xunit;
-
namespace ServiceLib.Tests.Manager;
public class CoreManagerTests
{
- [Theory]
- [InlineData(ECoreType.sing_box)]
- [InlineData(ECoreType.mihomo)]
- [InlineData(ECoreType.Xray)]
- public void ShouldRunAsSudo_TunLaunchOnNonWindows_RequiresElevation(ECoreType coreType)
+ [Test]
+ [Arguments(ECoreType.sing_box)]
+ [Arguments(ECoreType.mihomo)]
+ [Arguments(ECoreType.Xray)]
+ public async Task ShouldRunAsSudo_TunLaunchOnNonWindows_RequiresElevation(ECoreType coreType)
{
- CoreManager.ShouldRunAsSudo(isTunLaunch: true, coreType, isNonWindows: true).Should().BeTrue();
+ await CoreManager.ShouldRunAsSudo(isTunLaunch: true, coreType, isNonWindows: true).Should().BeTrue();
}
- [Fact]
- public void ShouldRunAsSudo_NonTunLaunch_ShouldNotElevate()
+ [Test]
+ public async Task ShouldRunAsSudo_NonTunLaunch_ShouldNotElevate()
{
// Regression guard for the macOS TUN failure: the elevation decision must follow
// the context snapshot that generated the config. A launch whose snapshot has TUN
// disabled must never elevate, and a launch whose snapshot has TUN enabled must
// elevate regardless of later changes to the live config.
- CoreManager.ShouldRunAsSudo(isTunLaunch: false, ECoreType.sing_box, isNonWindows: true).Should().BeFalse();
- CoreManager.ShouldRunAsSudo(isTunLaunch: false, ECoreType.Xray, isNonWindows: true).Should().BeFalse();
+ await CoreManager.ShouldRunAsSudo(isTunLaunch: false, ECoreType.sing_box, isNonWindows: true).Should().BeFalse();
+ await CoreManager.ShouldRunAsSudo(isTunLaunch: false, ECoreType.Xray, isNonWindows: true).Should().BeFalse();
}
- [Fact]
- public void ShouldRunAsSudo_OnWindows_ShouldNotElevate()
+ [Test]
+ public async Task ShouldRunAsSudo_OnWindows_ShouldNotElevate()
{
- CoreManager.ShouldRunAsSudo(isTunLaunch: true, ECoreType.sing_box, isNonWindows: false).Should().BeFalse();
+ await CoreManager.ShouldRunAsSudo(isTunLaunch: true, ECoreType.sing_box, isNonWindows: false).Should().BeFalse();
}
- [Theory]
- [InlineData(ECoreType.v2fly)]
- [InlineData(ECoreType.hysteria)]
- [InlineData(null)]
- public void ShouldRunAsSudo_UnsupportedCoreType_ShouldNotElevate(ECoreType? coreType)
+ [Test]
+ [Arguments(ECoreType.v2fly)]
+ [Arguments(ECoreType.hysteria)]
+ [Arguments(null)]
+ public async Task ShouldRunAsSudo_UnsupportedCoreType_ShouldNotElevate(ECoreType? coreType)
{
- CoreManager.ShouldRunAsSudo(isTunLaunch: true, coreType, isNonWindows: true).Should().BeFalse();
+ await CoreManager.ShouldRunAsSudo(isTunLaunch: true, coreType, isNonWindows: true).Should().BeFalse();
}
}
diff --git a/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj b/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj
index adefda0d..2dd3c7a3 100644
--- a/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj
+++ b/v2rayN/ServiceLib.Tests/ServiceLib.Tests.csproj
@@ -1,18 +1,23 @@
-
- Exe
- false
- true
-
+
+ Exe
+ false
+ enable
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+