216 lines
7.1 KiB
C#
216 lines
7.1 KiB
C#
using System.Text;
|
|
using FluentAssertions;
|
|
using AxCopilot.Handlers;
|
|
using Xunit;
|
|
|
|
namespace AxCopilot.Tests.Handlers;
|
|
|
|
public class ClipboardTransformTests
|
|
{
|
|
// ─── 대소문자 변환 ────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Upper_ConvertsToUppercase()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$upper", "hello world").Should().Be("HELLO WORLD");
|
|
}
|
|
|
|
[Fact]
|
|
public void Lower_ConvertsToLowercase()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$lower", "HELLO WORLD").Should().Be("hello world");
|
|
}
|
|
|
|
// ─── Base64 ──────────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Base64Encode_EncodesCorrectly()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$b64e", "hello").Should().Be("aGVsbG8=");
|
|
}
|
|
|
|
[Fact]
|
|
public void Base64Decode_DecodesCorrectly()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$b64d", "aGVsbG8=").Should().Be("hello");
|
|
}
|
|
|
|
[Fact]
|
|
public void Base64_RoundTrip()
|
|
{
|
|
var original = "AX Copilot 테스트";
|
|
var encoded = ClipboardHandler.ExecuteBuiltin("$b64e", original)!;
|
|
var decoded = ClipboardHandler.ExecuteBuiltin("$b64d", encoded);
|
|
decoded.Should().Be(original);
|
|
}
|
|
|
|
// ─── URL 인코딩 ──────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void UrlEncode_EncodesSpaces()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$urle", "hello world").Should().Be("hello%20world");
|
|
}
|
|
|
|
[Fact]
|
|
public void UrlDecode_DecodesSpaces()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$urld", "hello%20world").Should().Be("hello world");
|
|
}
|
|
|
|
[Fact]
|
|
public void UrlEncode_EncodesSpecialChars()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$urle", "a=b&c=d");
|
|
result.Should().Be("a%3Db%26c%3Dd");
|
|
}
|
|
|
|
[Fact]
|
|
public void UrlDecode_DecodesSpecialChars()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$urld", "a%3Db%26c%3Dd");
|
|
result.Should().Be("a=b&c=d");
|
|
}
|
|
|
|
// ─── 문자열 처리 ─────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Trim_RemovesLeadingTrailingWhitespace()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$trim", " hello ").Should().Be("hello");
|
|
}
|
|
|
|
[Fact]
|
|
public void Trim_PreservesInternalSpaces()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$trim", " hello world ").Should().Be("hello world");
|
|
}
|
|
|
|
[Fact]
|
|
public void Lines_RemovesEmptyLines()
|
|
{
|
|
var input = "a\n\nb\n \nc";
|
|
var result = ClipboardHandler.ExecuteBuiltin("$lines", input);
|
|
result.Should().NotContain("\n\n");
|
|
result.Should().Contain("a");
|
|
result.Should().Contain("b");
|
|
result.Should().Contain("c");
|
|
}
|
|
|
|
[Fact]
|
|
public void Lines_TrimsEachLine()
|
|
{
|
|
var input = " hello \n world ";
|
|
var result = ClipboardHandler.ExecuteBuiltin("$lines", input)!;
|
|
result.Should().Contain("hello");
|
|
result.Should().Contain("world");
|
|
result.Should().NotContain(" hello");
|
|
}
|
|
|
|
// ─── 타임스탬프 ──────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void Timestamp_EpochZero_Returns1970()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$ts", "0");
|
|
result.Should().NotBeNullOrEmpty();
|
|
result.Should().Contain("1970");
|
|
}
|
|
|
|
[Fact]
|
|
public void Timestamp_ValidEpoch_ReturnsDateString()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$ts", "1700000000");
|
|
result.Should().NotBeNullOrEmpty();
|
|
result.Should().MatchRegex(@"\d{4}-\d{2}-\d{2}");
|
|
}
|
|
|
|
[Fact]
|
|
public void Timestamp_InvalidInput_ReturnsNull()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$ts", "not-a-number").Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Epoch_ValidDate_ReturnsNumber()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$epoch", "1970-01-01");
|
|
result.Should().NotBeNullOrEmpty();
|
|
long.TryParse(result, out _).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Epoch_InvalidDate_ReturnsNull()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$epoch", "not-a-date").Should().BeNull();
|
|
}
|
|
|
|
// ─── JSON 포맷팅 ─────────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void JsonFormat_MinifiedJson_AddsIndentation()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$json", "{\"a\":1,\"b\":2}");
|
|
result.Should().NotBeNullOrEmpty();
|
|
result.Should().Contain("\n");
|
|
result.Should().Contain("\"a\"");
|
|
}
|
|
|
|
[Fact]
|
|
public void JsonFormat_AlreadyFormatted_StaysValid()
|
|
{
|
|
var formatted = "{\n \"a\": 1\n}";
|
|
var result = ClipboardHandler.ExecuteBuiltin("$json", formatted);
|
|
result.Should().NotBeNullOrEmpty();
|
|
result.Should().Contain("\"a\"");
|
|
}
|
|
|
|
[Fact]
|
|
public void JsonFormat_InvalidJson_ReturnsOriginal()
|
|
{
|
|
var invalid = "not json";
|
|
var result = ClipboardHandler.ExecuteBuiltin("$json", invalid);
|
|
result.Should().Be(invalid); // 파싱 실패 시 원본 반환
|
|
}
|
|
|
|
// ─── 마크다운 제거 ───────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void StripMarkdown_RemovesBold()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$md", "**bold text**");
|
|
result.Should().NotContain("**");
|
|
result.Should().Contain("bold text");
|
|
}
|
|
|
|
[Fact]
|
|
public void StripMarkdown_RemovesItalic()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$md", "*italic*");
|
|
result.Should().NotContain("*italic*");
|
|
result.Should().Contain("italic");
|
|
}
|
|
|
|
[Fact]
|
|
public void StripMarkdown_RemovesInlineCode()
|
|
{
|
|
var result = ClipboardHandler.ExecuteBuiltin("$md", "`code`");
|
|
result.Should().NotContain("`");
|
|
result.Should().Contain("code");
|
|
}
|
|
|
|
// ─── 알 수 없는 키 ──────────────────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void UnknownKey_ReturnsNull()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("$unknown", "input").Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void EmptyKey_ReturnsNull()
|
|
{
|
|
ClipboardHandler.ExecuteBuiltin("", "input").Should().BeNull();
|
|
}
|
|
}
|