<#/*THIS IS A T4 FILE - see t4_text_templating.md for what it is and how to run codegen*/#>
<#@ template debug="True" #>
<#@ output extension=".gen.cs" encoding="utf-8"#>
<#@ assembly name="System.Core" #>

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     TextTransform Samples/Packages/com.unity.collections/Unity.Collections.Tests/FixedStringSizedTests.tt
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#if !UNITY_DOTSRUNTIME
using System;
using NUnit.Framework;
using Unity.Collections;
using Unity.Collections.Tests;
#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
using UnityEngine;
#endif

namespace FixedStringTests
{

internal class FixedStringSizedTests
{
<#
var SIZES = new int[] {32,64,128,512,4096};
foreach(var BYTES in SIZES)
{
    // 2 bytes ushort + 1 byte space for null termination
    var ALMOST_TOO_BIG = new String('o', BYTES - 3);
    var TOO_BIG = new String('o', BYTES - 2);
#>

#if !UNITY_DOTSRUNTIME        // DOTS-Runtime doesn't support UnityEngine
    class ScriptableObjectFixedString<#=BYTES#>Bytes : UnityEngine.ScriptableObject
    {
        public FixedString<#=BYTES#>Bytes String;
    }

    [Test]
    public void FixedString<#=BYTES#>BytesSerializes()
    {
        var a = UnityEngine.ScriptableObject.CreateInstance<ScriptableObjectFixedString<#=BYTES#>Bytes>();
        a.String = "Hello World";
        var b = UnityEngine.Object.Instantiate(a);
        Assert.AreEqual(a.String, b.String);
    }
#endif

    [TestCase("<#=ALMOST_TOO_BIG#>", FormatError.None, TestName="FixedString<#=BYTES#>AtMaximumSizeWorks_Almost")]
    [TestCase("<#=TOO_BIG#>", FormatError.Overflow, TestName="FixedString<#=BYTES#>AtMaximumSizeWorks_Over")]
    public void FixedString<#=BYTES#>BytesAtMaximumSizeWorks(String a, FormatError expectedError)
    {
        FixedString<#=BYTES#>Bytes aa = default;
        aa.Junk();
        var error = aa.Append(a);
        Assert.AreEqual(expectedError, error);
        if (expectedError == FormatError.None)
            aa.AssertNullTerminated();
        else
            Assert.AreEqual(0, aa.Length);
    }

    [Test]
    public unsafe void FixedString<#=BYTES#>BytesToFixedList()
    {
        FixedString<#=BYTES#>Bytes a = default;
        a.Junk();
        a.Append("0123");
        ref var aList = ref a.AsFixedList();
        Assert.IsFalse(aList.IsEmpty);
        Assert.AreEqual(4, aList.Length);
        Assert.AreEqual(a.Capacity + 1, aList.Capacity);
        Assert.AreEqual('0', aList[0]);
        Assert.AreEqual('1', aList[1]);
        Assert.AreEqual('2', aList[2]);
        Assert.AreEqual('3', aList[3]);
        aList.Add((byte)'4');
        Assert.AreEqual("01234", a);
        // because we modified it as a FixedList, it will not be null terminated!
        Assert.AreNotEqual(0, a.GetUnsafePtr()[a.Length]);
    }

    [TestCase("red")]
    [TestCase("紅色", TestName="{m}(Chinese-Red)")]
    [TestCase("George Washington")]
    [TestCase("村上春樹", TestName="{m}(HarukiMurakami)")]
    public unsafe void FixedString<#=BYTES#>BytesEqualsStringNoGC(string a)
    {
        FixedString<#=BYTES#>Bytes b = a;
        GCAllocRecorder.ValidateNoGCAllocs(() =>
        {
            b.Equals(a);
        });
    }

<#
    foreach(var OTHERBYTES in SIZES)
    {
        if (OTHERBYTES != BYTES)
        {
#>

    [TestCase("red")]
    [TestCase("紅色", TestName="{m}(Chinese-Red)")]
    [TestCase("George Washington")]
    [TestCase("村上春樹", TestName="{m}(HarukiMurakami)")]
    public void FixedString<#=BYTES#>BytesToFixedString<#=OTHERBYTES#>Works(String a)
    {
        var b = new FixedString<#=BYTES#>Bytes(a);
        var c = new FixedString<#=OTHERBYTES#>Bytes(b);
        String d = c.ToString();
        Assert.AreEqual(a, d);
    }
<#
        }
    }
}
#>

}

}
#endif