mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 08:50:25 +01:00
This commit is contained in:
170
Tests/UnitTestsParallelizable/Drivers/UrlHyperlinkerTests.cs
Normal file
170
Tests/UnitTestsParallelizable/Drivers/UrlHyperlinkerTests.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
#nullable enable
|
||||
using System.Text;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace UnitTests_Parallelizable.DriverTests;
|
||||
|
||||
public class Osc8UrlLinkerTests (ITestOutputHelper output)
|
||||
{
|
||||
private readonly ITestOutputHelper _output = output;
|
||||
|
||||
[Theory]
|
||||
[InlineData ("<https://example.com>", "<", "https://example.com", ">")]
|
||||
[InlineData ("\"https://example.com\"", "\"", "https://example.com", "\"")]
|
||||
public void WrapOsc8_Does_Not_Cross_Delimiters (string input, string prefix, string url, string suffix)
|
||||
{
|
||||
string actual = Wrap (input);
|
||||
string expected = prefix + LinkWrappedWithOSCs (url) + suffix;
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("No url here")]
|
||||
[InlineData ("http://")]
|
||||
[InlineData ("://missing-scheme.com")]
|
||||
public void WrapOsc8_Leaves_Text_Unchanged_Without_Urls (string input)
|
||||
{
|
||||
StringBuilder sb = new (input);
|
||||
StringBuilder result = Osc8UrlLinker.WrapOsc8 (sb);
|
||||
|
||||
Assert.Same (sb, result);
|
||||
Assert.Equal (input, result.ToString ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WrapOsc8_Stops_At_Ansi_Escape_Sequence ()
|
||||
{
|
||||
var esc = "\x1B[38;2;173m";
|
||||
string input = "https://example.com" + esc + "/more";
|
||||
|
||||
string wrapped = Wrap (input);
|
||||
string expected = LinkWrappedWithOSCs ("https://example.com") + esc + "/more";
|
||||
Assert.Equal (expected, wrapped);
|
||||
|
||||
// Verify that the hyperlinked visible content contains no ESC
|
||||
string start = EscSeqUtils.OSC_StartHyperlink ("https://example.com");
|
||||
string end = EscSeqUtils.OSC_EndHyperlink ();
|
||||
int s = wrapped.IndexOf (start, StringComparison.Ordinal);
|
||||
Assert.True (s >= 0);
|
||||
|
||||
int e = wrapped.IndexOf (end, s + start.Length, StringComparison.Ordinal);
|
||||
Assert.True (e > s);
|
||||
|
||||
int contentStart = s + start.Length;
|
||||
int contentLength = e - contentStart;
|
||||
string visible = wrapped.Substring (contentStart, contentLength);
|
||||
|
||||
Assert.DoesNotContain ('\x1B', visible);
|
||||
Assert.Equal ("https://example.com", visible);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("See https://example.com/path.", "See ", "https://example.com/path", ".")]
|
||||
[InlineData ("See https://example.com/file.tar.gz,", "See ", "https://example.com/file.tar.gz", ",")]
|
||||
[InlineData ("See https://example.com/path_(with)_parens)", "See ", "https://example.com/path_(with)_parens", ")")]
|
||||
public void WrapOsc8_Trims_Trailing_Punctuation (string input, string prefix, string url, string suffix)
|
||||
{
|
||||
string actual = Wrap (input);
|
||||
string expected = prefix + LinkWrappedWithOSCs (url) + suffix;
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (
|
||||
"Multiple: https://a.com, https://b.com!",
|
||||
"Multiple: ",
|
||||
"https://a.com",
|
||||
", ",
|
||||
"https://b.com",
|
||||
"!")]
|
||||
[InlineData (
|
||||
"List https://one.com https://two.com https://three.com",
|
||||
"List ",
|
||||
"https://one.com",
|
||||
" ",
|
||||
"https://two.com",
|
||||
" ",
|
||||
"https://three.com",
|
||||
"")]
|
||||
public void WrapOsc8_Wraps_Multiple_Urls (string input, params string [] segments)
|
||||
{
|
||||
// segments: text0, url1, text1, [url2, text2]...
|
||||
string expected = BuildExpected (segments);
|
||||
|
||||
string actual = Wrap (input);
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData ("https://github.com", "https://github.com")]
|
||||
[InlineData ("http://example.com", "http://example.com")]
|
||||
[InlineData ("ftp://ftp.example.com/file.zip", "ftp://ftp.example.com/file.zip")]
|
||||
[InlineData ("https://example.com:8080/path", "https://example.com:8080/path")]
|
||||
[InlineData ("https://example.com/path#anchor", "https://example.com/path#anchor")]
|
||||
[InlineData ("https://example.com/path?query=value&other=123", "https://example.com/path?query=value&other=123")]
|
||||
[InlineData ("https://commons.wikimedia.org/wiki/File:Spinning_globe.gif", "https://commons.wikimedia.org/wiki/File:Spinning_globe.gif")]
|
||||
public void WrapOsc8_Wraps_Standalone_Url (string input, string expectedUrl)
|
||||
{
|
||||
string actual = Wrap (input);
|
||||
string expected = LinkWrappedWithOSCs (expectedUrl);
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (
|
||||
"Visit https://github.com for more info",
|
||||
"Visit ",
|
||||
"https://github.com",
|
||||
" for more info")]
|
||||
[InlineData (
|
||||
"Check out https://commons.wikimedia.org/wiki/File:Spinning_globe.gif!",
|
||||
"Check out ",
|
||||
"https://commons.wikimedia.org/wiki/File:Spinning_globe.gif",
|
||||
"!")]
|
||||
[InlineData (
|
||||
"URLs: https://example.com and http://other.com",
|
||||
"URLs: ",
|
||||
"https://example.com",
|
||||
" and ",
|
||||
"http://other.com",
|
||||
"")]
|
||||
public void WrapOsc8_Wraps_Urls_In_Text (string input, params string [] segments)
|
||||
{
|
||||
// segments: text0, url1, text1, [url2, text2]...
|
||||
string expected = BuildExpected (segments);
|
||||
|
||||
string actual = Wrap (input);
|
||||
Assert.Equal (expected, actual);
|
||||
}
|
||||
|
||||
private static string BuildExpected (string [] segments)
|
||||
{
|
||||
// segments must be: text0, url1, text1, url2, text2, ...
|
||||
string expected = segments.Length > 0 ? segments [0] : string.Empty;
|
||||
|
||||
for (var i = 1; i + 1 < segments.Length; i += 2)
|
||||
{
|
||||
string url = segments [i];
|
||||
string textAfter = segments [i + 1];
|
||||
|
||||
expected += LinkWrappedWithOSCs (url);
|
||||
expected += textAfter;
|
||||
}
|
||||
|
||||
return expected;
|
||||
}
|
||||
|
||||
private static string LinkWrappedWithOSCs (string url, string? display = null)
|
||||
{
|
||||
display ??= url;
|
||||
|
||||
return EscSeqUtils.OSC_StartHyperlink (url) + display + EscSeqUtils.OSC_EndHyperlink ();
|
||||
}
|
||||
|
||||
private static string Wrap (string input)
|
||||
{
|
||||
StringBuilder sb = new (input);
|
||||
|
||||
return Osc8UrlLinker.WrapOsc8 (sb).ToString ();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user