123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- using System;
- using NUnit.Framework;
- using Unity.Collections;
- using Unity.Collections.LowLevel.Unsafe;
- using System.Text;
- using Unity.Burst;
- using Unity.Jobs;
-
- namespace Unity.Collections.Tests
- {
- internal class UnsafeTextTests
- {
- void AssertAreEqualInTest(string expected, in UnsafeText actual)
- {
- var actualString = actual.ToString();
- Assert.AreEqual(expected, actualString);
- }
-
- // NOTE: If you call this function from Mono and T is not marshalable - your app (Editor or the player built with Mono scripting backend) could/will crash.
- bool IsMarshalable<T>() where T : unmanaged
- {
- try
- {
- unsafe
- {
- var size = System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));
- IntPtr memoryIntPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(size);
- try
- {
- var obj = new T();
- System.Runtime.InteropServices.Marshal.StructureToPtr(obj, memoryIntPtr, false);
- System.Runtime.InteropServices.Marshal.DestroyStructure<T>(memoryIntPtr);
- }
- finally
- {
- System.Runtime.InteropServices.Marshal.FreeHGlobal(memoryIntPtr);
- }
-
- return true;
- }
- }
- catch (Exception e)
- {
- UnityEngine.Debug.LogError("ERROR in IsMarshalable<" + typeof(T).FullName + "> " + e);
- return false;
- }
- }
-
- [Test]
- public void UnsafeTextIsMarshalable()
- {
- var result = IsMarshalable<UnsafeText>();
- Assert.IsTrue(result);
- }
-
- [Test]
- public unsafe void UnsafeTextCorrectBinaryHeader()
- {
- var text = new UnsafeText(42, Allocator.Persistent);
- var ptr = text.GetUnsafePtr();
-
- Assert.AreEqual(0 + 1, text.m_UntypedListData.m_length);
- Assert.AreEqual(Allocator.Persistent, text.m_UntypedListData.Allocator.ToAllocator);
- Assert.IsTrue(ptr == text.m_UntypedListData.Ptr, "ptr != text.m_UntypedListData.Ptr");
-
- var listOfBytesCast = text.AsUnsafeListOfBytes();
-
- Assert.AreEqual(0 + 1, listOfBytesCast.Length);
- Assert.AreEqual(Allocator.Persistent, listOfBytesCast.Allocator.ToAllocator);
- Assert.IsTrue(ptr == listOfBytesCast.Ptr, "ptr != listOfBytesCast.Ptr");
-
- Assert.AreEqual(text.m_UntypedListData.m_capacity, listOfBytesCast.Capacity);
-
- text.Dispose();
- }
-
- [Test]
- public void UnsafeTextCorrectLengthAfterClear()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- Assert.True(aa.IsCreated);
- Assert.AreEqual(0, aa.Length, "Length after creation is not 0");
- aa.AssertNullTerminated();
-
- aa.Junk();
-
- aa.Clear();
- Assert.AreEqual(0, aa.Length, "Length after clear is not 0");
- aa.AssertNullTerminated();
-
- aa.Dispose();
- }
-
- [Test]
- public void UnsafeTextFormatExtension1Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- Assert.True(aa.IsCreated);
- aa.Junk();
- FixedString32Bytes format = "{0}";
- FixedString32Bytes arg0 = "a";
- aa.AppendFormat(format, arg0);
- aa.Append('a');
- aa.AssertNullTerminated();
- AssertAreEqualInTest("aa", aa);
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension2Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString32Bytes format = "{0} {1}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- aa.AppendFormat(format, arg0, arg1);
- AssertAreEqualInTest("a b", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension3Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString32Bytes format = "{0} {1} {2}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- aa.AppendFormat(format, arg0, arg1, arg2);
- AssertAreEqualInTest("a b c", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension4Params()
- {
- UnsafeText aa = new UnsafeText(512, Allocator.Temp);
- aa.Junk();
- FixedString32Bytes format = "{0} {1} {2} {3}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3);
- AssertAreEqualInTest("a b c d", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension5Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString32Bytes format = "{0} {1} {2} {3} {4}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- FixedString32Bytes arg4 = "e";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3, arg4);
- AssertAreEqualInTest("a b c d e", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension6Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString32Bytes format = "{0} {1} {2} {3} {4} {5}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- FixedString32Bytes arg4 = "e";
- FixedString32Bytes arg5 = "f";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5);
- AssertAreEqualInTest("a b c d e f", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension7Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString32Bytes format = "{0} {1} {2} {3} {4} {5} {6}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- FixedString32Bytes arg4 = "e";
- FixedString32Bytes arg5 = "f";
- FixedString32Bytes arg6 = "g";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
- AssertAreEqualInTest("a b c d e f g", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension8Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString128Bytes format = "{0} {1} {2} {3} {4} {5} {6} {7}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- FixedString32Bytes arg4 = "e";
- FixedString32Bytes arg5 = "f";
- FixedString32Bytes arg6 = "g";
- FixedString32Bytes arg7 = "h";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
- AssertAreEqualInTest("a b c d e f g h", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension9Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString128Bytes format = "{0} {1} {2} {3} {4} {5} {6} {7} {8}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- FixedString32Bytes arg4 = "e";
- FixedString32Bytes arg5 = "f";
- FixedString32Bytes arg6 = "g";
- FixedString32Bytes arg7 = "h";
- FixedString32Bytes arg8 = "i";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
- AssertAreEqualInTest("a b c d e f g h i", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
-
- [Test]
- public void UnsafeTextFormatExtension10Params()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- FixedString128Bytes format = "{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}";
- FixedString32Bytes arg0 = "a";
- FixedString32Bytes arg1 = "b";
- FixedString32Bytes arg2 = "c";
- FixedString32Bytes arg3 = "d";
- FixedString32Bytes arg4 = "e";
- FixedString32Bytes arg5 = "f";
- FixedString32Bytes arg6 = "g";
- FixedString32Bytes arg7 = "h";
- FixedString32Bytes arg8 = "i";
- FixedString32Bytes arg9 = "j";
- aa.AppendFormat(format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
- AssertAreEqualInTest("a b c d e f g h i j", aa);
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
- [Test]
- public void UnsafeTextAppendGrows()
- {
- UnsafeText aa = new UnsafeText(1, Allocator.Temp);
- var origCapacity = aa.Capacity;
- for (int i = 0; i < origCapacity; ++i)
- aa.Append('a');
- Assert.AreEqual(origCapacity, aa.Capacity);
- aa.Append('b');
- Assert.GreaterOrEqual(aa.Capacity, origCapacity);
- Assert.AreEqual(new String('a', origCapacity) + "b", aa.ToString());
- aa.Dispose();
- }
-
- [Test]
- public void UnsafeTextAppendString()
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Append("aa");
- Assert.AreEqual("aa", aa.ToString());
- aa.Append("bb");
- Assert.AreEqual("aabb", aa.ToString());
- aa.Dispose();
- }
-
-
- [TestCase("Antidisestablishmentarianism")]
- [TestCase("🌹🌻🌷🌿🌵🌾")]
- public void UnsafeTextCopyFromBytesWorks(String a)
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Junk();
- var utf8 = Encoding.UTF8.GetBytes(a);
- unsafe
- {
- fixed (byte* b = utf8)
- aa.Append(b, (ushort) utf8.Length);
- }
-
- Assert.AreEqual(a, aa.ToString());
- aa.AssertNullTerminated();
-
- aa.Append("tail");
- Assert.AreEqual(a + "tail", aa.ToString());
- aa.AssertNullTerminated();
-
- aa.Dispose();
- }
-
- [TestCase("red")]
- [TestCase("紅色", TestName = "{m}(Chinese-Red)")]
- [TestCase("George Washington")]
- [TestCase("村上春樹", TestName = "{m}(HarukiMurakami)")]
- public void UnsafeTextToStringWorks(String a)
- {
- UnsafeText aa = new UnsafeText(4, Allocator.Temp);
- aa.Append(new FixedString128Bytes(a));
- Assert.AreEqual(a, aa.ToString());
- aa.AssertNullTerminated();
- aa.Dispose();
- }
-
- [Test]
- public void UnsafeTextIndexOf()
- {
- UnsafeText a = new UnsafeText(16, Allocator.Temp);
- a.Append((FixedString64Bytes) "bookkeeper bookkeeper");
- UnsafeText b = new UnsafeText(8, Allocator.Temp);
- b.Append((FixedString32Bytes) "ookkee");
-
- Assert.AreEqual(1, a.IndexOf(b));
- Assert.AreEqual(-1, b.IndexOf(a));
- a.Dispose();
- b.Dispose();
- }
-
- [Test]
- public void UnsafeTextLastIndexOf()
- {
- UnsafeText a = new UnsafeText(16, Allocator.Temp);
- a.Append((FixedString64Bytes) "bookkeeper bookkeeper");
- UnsafeText b = new UnsafeText(8, Allocator.Temp);
- b.Append((FixedString32Bytes) "ookkee");
-
- Assert.AreEqual(12, a.LastIndexOf(b));
- Assert.AreEqual(-1, b.LastIndexOf(a));
- a.Dispose();
- b.Dispose();
- }
-
- [Test]
- public void UnsafeTextContains()
- {
- UnsafeText a = new UnsafeText(16, Allocator.Temp);
- a.Append((FixedString64Bytes) "bookkeeper bookkeeper");
- UnsafeText b = new UnsafeText(8, Allocator.Temp);
- b.Append((FixedString32Bytes) "ookkee");
-
- Assert.AreEqual(true, a.Contains(b));
- a.Dispose();
- b.Dispose();
- }
-
- [Test]
- public void UnsafeTextComparisons()
- {
- UnsafeText a = new UnsafeText(16, Allocator.Temp);
- a.Append((FixedString64Bytes) "apple");
- UnsafeText b = new UnsafeText(8, Allocator.Temp);
- b.Append((FixedString32Bytes) "banana");
-
- Assert.AreEqual(false, a.Equals(b));
- Assert.AreEqual(true, !b.Equals(a));
- a.Dispose();
- b.Dispose();
- }
-
- [Test]
- public void UnsafeText_CustomAllocatorTest()
- {
- AllocatorManager.Initialize();
- var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
- ref var allocator = ref allocatorHelper.Allocator;
- allocator.Initialize();
-
- using (var container = new UnsafeText(1, allocator.Handle))
- {
- }
-
- Assert.IsTrue(allocator.WasUsed);
- allocator.Dispose();
- allocatorHelper.Dispose();
- AllocatorManager.Shutdown();
- }
-
- [BurstCompile]
- struct BurstedCustomAllocatorJob : IJob
- {
- [NativeDisableUnsafePtrRestriction]
- public unsafe CustomAllocatorTests.CountingAllocator* Allocator;
-
- public void Execute()
- {
- unsafe
- {
- using (var container = new UnsafeText(1, Allocator->Handle))
- {
- }
- }
- }
- }
-
- [Test]
- public unsafe void UnsafeText_BurstedCustomAllocatorTest()
- {
- AllocatorManager.Initialize();
- var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
- ref var allocator = ref allocatorHelper.Allocator;
- allocator.Initialize();
-
- var allocatorPtr = (CustomAllocatorTests.CountingAllocator*)UnsafeUtility.AddressOf<CustomAllocatorTests.CountingAllocator>(ref allocator);
- unsafe
- {
- var handle = new BurstedCustomAllocatorJob {Allocator = allocatorPtr}.Schedule();
- handle.Complete();
- }
-
- Assert.IsTrue(allocator.WasUsed);
- allocator.Dispose();
- allocatorHelper.Dispose();
- AllocatorManager.Shutdown();
- }
-
- [TestCase("red", 'r', 'd')]
- [TestCase("紅色", '紅', '色')]
- [TestCase("црвена", 'ц', 'а')]
- [TestCase("George Washington", 'G', 'n')]
- [TestCase("村上春樹", '村', '樹')]
- [TestCase("로마는 하루아침에 이루어진 것이 아니다", '로', '다')]
- [TestCase("Лако ти је плитку воду замутити и будалу наљутити", 'Л', 'и')]
- [TestCase("Үнэн үг хэлсэн хүнд ноёд өстэй, үхэр унасан хүнд ноход өстэй.", 'Ү', '.')]
- public void UnsafeText_StartsEndsWithChar(String a, char starts, char ends)
- {
- UnsafeText actual = new UnsafeText(16, Allocator.Temp);
- actual.Append(a);
- Assert.True(actual.StartsWith(starts));
- Assert.True(actual.EndsWith(ends));
- }
-
- [TestCase("red", "r", "d")]
- [TestCase("紅色", "紅", "色")]
- [TestCase("црвена", "црв", "ена")]
- [TestCase("George Washington", "George", "Washington")]
- [TestCase("村上春樹", "村上", "春樹")]
- [TestCase("🌕🌖🌗🌘🌑🌒🌓🌔", "🌕🌖🌗", "🌒🌓🌔")]
- [TestCase("𝒞𝒯𝒮𝒟𝒳𝒩𝒫𝒢", "𝒞𝒯𝒮", "𝒩𝒫𝒢")]
- [TestCase("로마는 하루아침에 이루어진 것이 아니다", "로마는", "아니다")]
- [TestCase("Лако ти је плитку воду замутити и будалу наљутити", "Лако", "наљутити")]
- [TestCase("Үнэн үг хэлсэн хүнд ноёд өстэй, үхэр унасан хүнд ноход өстэй.", "Үнэн", "өстэй.")]
- public void UnsafeText_StartsEndsWithString(String a, String starts, String ends)
- {
- UnsafeText actual = new UnsafeText(16, Allocator.Temp);
- actual.Append(a);
-
- Assert.True(actual.StartsWith((FixedString64Bytes)starts));
- Assert.True(actual.EndsWith((FixedString64Bytes)ends));
- }
-
- [TestCase("red ", ' ', "red ", "red", "red")]
- [TestCase(" red ", ' ', "red ", " red", "red")]
- [TestCase(" ", ' ', "", "", "")]
- public void UnsafeText_TrimStart(String a, char trim, String expectedStart, String expectedEnd, String expected)
- {
- UnsafeText actual = new UnsafeText(16, Allocator.Temp);
- actual.Append(a);
-
- Assert.AreEqual(expectedStart, actual.TrimStart(Allocator.Temp).ToString());
- Assert.AreEqual(expectedEnd, actual.TrimEnd(Allocator.Temp).ToString());
- Assert.AreEqual(expected, actual.Trim(Allocator.Temp).ToString());
- }
-
- [TestCase(" red ", "ed ", " red", "ed")]
- [TestCase("црвена", "црвена", "црвена", "црвена")]
- [TestCase(" ", "", "", "")]
- public void UnsafeText_TrimStartWithRunes(String a, String expectedStart, String expectedEnd, String expected)
- {
- UnsafeText actual = new UnsafeText(16, Allocator.Temp);
- actual.Append(a);
-
- Assert.AreEqual(expectedStart, actual.TrimStart(Allocator.Temp, new Unicode.Rune[] { ' ', 'r' }).ToString());
- Assert.AreEqual(expectedEnd, actual.TrimEnd(Allocator.Temp, new Unicode.Rune[] { ' ', 'r' }).ToString());
- Assert.AreEqual(expected, actual.Trim(Allocator.Temp, new Unicode.Rune[] { ' ', 'r' }).ToString());
- }
-
- [TestCase("Red", "red", "RED")]
- [TestCase("црвена", "црвена", "црвена")]
- [TestCase(" ", " ", " ")]
- public void UnsafeText_ToLowerUpperAscii(String a, String expectedLower, String expectedUpped)
- {
- UnsafeText actual = new UnsafeText(16, Allocator.Temp);
- actual.Append(a);
-
- Assert.AreEqual(expectedLower, actual.ToLowerAscii(Allocator.Temp).ToString());
- Assert.AreEqual(expectedUpped, actual.ToUpperAscii(Allocator.Temp).ToString());
- }
- }
- }
|