解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
3.59 KiB
X
using System.ComponentModel;
using NewLife.Buffers;
using NewLife.Collections;
using Xunit;

namespace XUnitTest.Buffers;

[DisplayName("数组池缓冲句柄")]
public class PoolBufferTests
{
    [Fact]
    [DisplayName("借出_Length与Span为请求长度且可读写")]
    public void Rent_Basic()
    {
        using var buffer = Pool.Rent(100);

        Assert.Equal(100, buffer.Length);
        Assert.Equal(100, buffer.Span.Length);
        Assert.True(buffer.Buffer.Length >= 100);

        buffer.Span[0] = 0x12;
        buffer.Buffer[1] = 0x34;

        Assert.Equal(0x12, buffer.Buffer[0]);
        Assert.Equal(0x34, buffer.Buffer[1]);
    }

    [Fact]
    [DisplayName("长度语义_Span只覆盖请求长度_Buffer可能更长")]
    public void LengthSemantics()
    {
        using var buffer = Pool.Rent(3);

        Assert.Equal(3, buffer.Length);
        Assert.Equal(3, buffer.Span.Length);
        Assert.True(buffer.Buffer.Length >= 3);

        // 写满请求部分不越界
        buffer.Span.Fill(0x5A);
        Assert.Equal(0x5A, buffer.Buffer[2]);
    }

    [Fact]
    [DisplayName("索引器_可直接读写元素")]
    public void Indexer()
    {
        using var buffer = Pool.Rent(4);

        buffer[0] = 0x11;
        buffer[1] = 0x22;
        buffer[1] |= 0x33;      // 复合赋值走 ref 索引器

        Assert.Equal(0x11, buffer.Buffer[0]);
        Assert.Equal(0x33, buffer.Buffer[1]);
    }

    [Fact]
    [DisplayName("隐式转换_与Buffer指向同一数组")]
    public void ImplicitConvert()
    {
        using var buffer = Pool.Rent(16);

        Byte[] array = buffer;
        Assert.Same(buffer.Buffer, array);

        // 隐式转换后可直接当数组实参传入
        Assert.True(ArrayLength(buffer) >= 16);
    }

    private static Int32 ArrayLength(Byte[] value) => value.Length;

    [Fact]
    [DisplayName("借出与归还_不产生堆分配")]
    public void Rent_Dispose_NoAllocation()
    {
        // 预热:首次借出由池新建数组
        using (var warm = Pool.Rent(1024))
        {
            warm.Buffer[0] = 1;
        }

        var memory = GC.GetAllocatedBytesForCurrentThread();

        Int32 length;
        using (var buffer = Pool.Rent(1024))
        {
            length = buffer.Length;
            buffer.Span[0] = 0x5A;
        }

        var used = GC.GetAllocatedBytesForCurrentThread() - memory;

        Assert.Equal(0, used);
        Assert.Equal(1024, length);
    }

    [Fact]
    [DisplayName("归还_数组回到池中并可被再次借出")]
    public void Dispose_ReturnToPool()
    {
        Byte[] first;
        using (var buffer = Pool.Rent(64))
        {
            first = buffer.Buffer;
        }

        // 同线程内归还的数组会被池优先复用
        using var again = Pool.Rent(64);
        Assert.Same(first, again.Buffer);
    }

    [Fact]
    [DisplayName("默认实例_空实现可安全释放")]
    public void DefaultInstance()
    {
        using var empty = default(PoolBuffer<Byte>);

        Assert.Equal(0, empty.Length);
        Assert.True(empty.Span.IsEmpty);
        Assert.Null(empty.Buffer);
    }

    [Fact]
    [DisplayName("字符缓冲_借出后按下标写入并取用")]
    public void RentChars()
    {
        const Int32 size = 600;
        using var chars = Pool.Rent<Char>(size);

        Assert.Equal(size, chars.Length);
        Assert.Equal(size, chars.Span.Length);

        for (var i = 0; i < size; i++)
            chars[i] = (Char)('A' + i % 26);

        Assert.Equal('A', chars[0]);
        Assert.Equal('B', chars[1]);
        Assert.Equal("ABC", new String(chars.Span[..3]));
    }
}