diff --git a/BililiveRecorder.Core/RoomIdFromUrl.cs b/BililiveRecorder.Core/RoomIdFromUrl.cs new file mode 100644 index 0000000..55f360f --- /dev/null +++ b/BililiveRecorder.Core/RoomIdFromUrl.cs @@ -0,0 +1,9 @@ +using System.Text.RegularExpressions; + +namespace BililiveRecorder.Core +{ + public static class RoomIdFromUrl + { + public static readonly Regex Regex = new Regex("""^(?:(?:https?:\/\/)?live\.bilibili\.com\/(?:blanc\/|h5\/)?)?(\d+)\/?(?:[#\?].*)?$""", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase); + } +} diff --git a/BililiveRecorder.WPF/Pages/RoomListPage.xaml.cs b/BililiveRecorder.WPF/Pages/RoomListPage.xaml.cs index 6f2965f..3d628d1 100644 --- a/BililiveRecorder.WPF/Pages/RoomListPage.xaml.cs +++ b/BililiveRecorder.WPF/Pages/RoomListPage.xaml.cs @@ -23,9 +23,6 @@ namespace BililiveRecorder.WPF.Pages public partial class RoomListPage { private static readonly ILogger logger = Log.ForContext(); - private static readonly Regex RoomIdRegex - = new Regex(@"^(?:https?:\/\/)?live\.bilibili\.com\/(?:blanc\/|h5\/)?(\d*)(?:\?.*)?$", - RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled); private readonly IRoom?[] NullRoom = new IRoom?[] { null }; @@ -159,7 +156,7 @@ namespace BililiveRecorder.WPF.Pages if (!int.TryParse(input, out var roomid)) { - var m = RoomIdRegex.Match(input); + var m = RoomIdFromUrl.Regex.Match(input); if (m.Success && m.Groups.Count > 1 && int.TryParse(m.Groups[1].Value, out var result2)) { roomid = result2; diff --git a/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt b/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt index 9471bb6..4480862 100644 --- a/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt +++ b/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt @@ -474,6 +474,10 @@ namespace BililiveRecorder.Core public readonly Microsoft.Extensions.Caching.Memory.MemoryCache memoryCache; public PollyPolicy() { } } + public static class RoomIdFromUrl + { + public static readonly System.Text.RegularExpressions.Regex Regex; + } public class RoomStats : System.ComponentModel.INotifyPropertyChanged { public RoomStats() { } diff --git a/test/BililiveRecorder.Core.UnitTests/RoomIdFromUrlTests.cs b/test/BililiveRecorder.Core.UnitTests/RoomIdFromUrlTests.cs new file mode 100644 index 0000000..fdd22b1 --- /dev/null +++ b/test/BililiveRecorder.Core.UnitTests/RoomIdFromUrlTests.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using Xunit; + +namespace BililiveRecorder.Core.UnitTests +{ + public class RoomIdFromUrlTests + { + [Theory] + [MemberData(nameof(ShouldMatchData))] + public void ShouldMatch(string id, string url) + { + var m = RoomIdFromUrl.Regex.Match(url); + Assert.True(m.Success); + Assert.Equal(id, m.Groups[1].Value); + } + + public static TheoryData ShouldMatchData() + { + var data = new TheoryData(); + + static IEnumerable basePaths() + { + yield return "123"; + yield return "123?abc=def"; + yield return "123#anything"; + yield return "123#/"; + yield return "123?abc=def#anything"; + + yield return "123/"; + yield return "123/?abc=def"; + yield return "123/#anything"; + yield return "123/#/"; + yield return "123/?abc=def#anything"; + } + + var prefix = new[] + { + "live.bilibili.com/", + "http://live.bilibili.com/", + "https://live.bilibili.com/", + "live.bilibili.com/blanc/", + "http://live.bilibili.com/blanc/", + "https://live.bilibili.com/blanc/", + "live.bilibili.com/h5/", + "http://live.bilibili.com/h5/", + "https://live.bilibili.com/h5/", + }; + + foreach (var p in prefix) + { + foreach (var b in basePaths()) + { + data.Add("123", p + b); + } + } + + return data; + } + + [Theory] + [MemberData(nameof(ShouldNotMatchData))] + public void ShouldNotMatch(string url) + { + Assert.DoesNotMatch(RoomIdFromUrl.Regex, url); + } + + public static TheoryData ShouldNotMatchData() + { + var data = new TheoryData + { + "https://live.bilibili.com/123/a", + "https://live.bilibili.com/123a", + "https://live.bilibili.com/123a/", + "https://live.bilibili.com/notnumber", + "live.bilibili.com/otherpage/123", + "ftp://live.bilibili.com/123" + }; + + return data; + } + } +}