112 lines
3.4 KiB
C#
112 lines
3.4 KiB
C#
using SuiteLink.Client.Protocol;
|
|
|
|
namespace SuiteLink.Client.Tests.Protocol;
|
|
|
|
public sealed class SuiteLinkEncodingTests
|
|
{
|
|
[Fact]
|
|
public void EncodeLengthPrefixedUtf16_WithAsciiText_WritesCharacterCountAndUtf16Bytes()
|
|
{
|
|
var bytes = SuiteLinkEncoding.EncodeLengthPrefixedUtf16("AB");
|
|
|
|
Assert.Equal(new byte[] { 0x02, 0x41, 0x00, 0x42, 0x00 }, bytes);
|
|
}
|
|
|
|
[Fact]
|
|
public void DecodeNullTerminatedUtf16_ReadsStringAndConsumedBytes()
|
|
{
|
|
var buffer = new byte[] { 0x48, 0x00, 0x69, 0x00, 0x00, 0x00, 0x20, 0x00 };
|
|
|
|
var text = SuiteLinkEncoding.DecodeNullTerminatedUtf16(buffer, out var consumed);
|
|
|
|
Assert.Equal("Hi", text);
|
|
Assert.Equal(6, consumed);
|
|
}
|
|
|
|
[Fact]
|
|
public void WriteAndReadUInt32LittleEndian_RoundTripsValue()
|
|
{
|
|
Span<byte> bytes = stackalloc byte[4];
|
|
|
|
SuiteLinkEncoding.WriteUInt32LittleEndian(bytes, 0x11223344);
|
|
var value = SuiteLinkEncoding.ReadUInt32LittleEndian(bytes);
|
|
|
|
Assert.Equal((uint)0x11223344, value);
|
|
Assert.Equal(new byte[] { 0x44, 0x33, 0x22, 0x11 }, bytes.ToArray());
|
|
}
|
|
|
|
[Fact]
|
|
public void FileTimeToUtcDateTime_ConvertsKnownEpochValue()
|
|
{
|
|
const long unixEpochFileTime = 116444736000000000L;
|
|
|
|
var value = SuiteLinkEncoding.FileTimeToUtcDateTime(unixEpochFileTime);
|
|
|
|
Assert.Equal(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), value);
|
|
}
|
|
|
|
[Fact]
|
|
public void DecodeNullTerminatedUtf16_WithOddLength_ThrowsFormatException()
|
|
{
|
|
var buffer = new byte[] { 0x41, 0x00, 0x00 };
|
|
|
|
Assert.Throws<FormatException>(() => SuiteLinkEncoding.DecodeNullTerminatedUtf16(buffer, out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void DecodeNullTerminatedUtf16_WithoutNullTerminator_ThrowsFormatException()
|
|
{
|
|
var buffer = new byte[] { 0x41, 0x00, 0x42, 0x00 };
|
|
|
|
Assert.Throws<FormatException>(() => SuiteLinkEncoding.DecodeNullTerminatedUtf16(buffer, out _));
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodeLengthPrefixedUtf16_WhenInputIsTooLong_ThrowsArgumentOutOfRangeException()
|
|
{
|
|
var value = new string('A', 256);
|
|
|
|
Assert.Throws<ArgumentOutOfRangeException>(() => SuiteLinkEncoding.EncodeLengthPrefixedUtf16(value));
|
|
}
|
|
|
|
[Fact]
|
|
public void EncodeLengthPrefixedUtf16_WithSurrogatePair_PrefixUsesUtf16CodeUnits()
|
|
{
|
|
var bytes = SuiteLinkEncoding.EncodeLengthPrefixedUtf16("A\U0001F600");
|
|
|
|
Assert.Equal(3, bytes[0]);
|
|
}
|
|
|
|
[Fact]
|
|
public void ReadUInt32LittleEndian_WhenInputIsTooShort_ThrowsFormatException()
|
|
{
|
|
var buffer = new byte[] { 0x01, 0x02, 0x03 };
|
|
|
|
Assert.Throws<FormatException>(() => SuiteLinkEncoding.ReadUInt32LittleEndian(buffer));
|
|
}
|
|
|
|
[Fact]
|
|
public void WriteAndReadSingleLittleEndian_RoundTripsNonTrivialValue()
|
|
{
|
|
Span<byte> bytes = stackalloc byte[4];
|
|
const float expected = 123.4567f;
|
|
|
|
SuiteLinkEncoding.WriteSingleLittleEndian(bytes, expected);
|
|
var value = SuiteLinkEncoding.ReadSingleLittleEndian(bytes);
|
|
|
|
Assert.Equal(expected, value);
|
|
}
|
|
|
|
[Fact]
|
|
public void WriteAndReadSingleLittleEndian_RoundTripsNaN()
|
|
{
|
|
Span<byte> bytes = stackalloc byte[4];
|
|
var expected = float.NaN;
|
|
|
|
SuiteLinkEncoding.WriteSingleLittleEndian(bytes, expected);
|
|
var value = SuiteLinkEncoding.ReadSingleLittleEndian(bytes);
|
|
|
|
Assert.True(float.IsNaN(value));
|
|
}
|
|
}
|