FormattingBufferHelperTests.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using Avalonia.Media.TextFormatting;
  5. using Avalonia.Utilities;
  6. using Xunit;
  7. namespace Avalonia.Base.UnitTests.Media.TextFormatting
  8. {
  9. public class FormattingBufferHelperTests
  10. {
  11. public static TheoryData<int> SmallSizes => new() { 1, 500, 10_000, 125_000 };
  12. public static TheoryData<int> LargeSizes => new() { 500_000, 1_000_000 };
  13. [Theory]
  14. [MemberData(nameof(SmallSizes))]
  15. public void Should_Keep_Small_Buffer_List(int itemCount)
  16. {
  17. var capacity = FillAndClearList(itemCount);
  18. Assert.True(capacity >= itemCount);
  19. }
  20. [Theory]
  21. [MemberData(nameof(LargeSizes))]
  22. public void Should_Reset_Large_Buffer_List(int itemCount)
  23. {
  24. var capacity = FillAndClearList(itemCount);
  25. Assert.Equal(0, capacity);
  26. }
  27. private static int FillAndClearList(int itemCount)
  28. {
  29. var list = new List<int>();
  30. for (var i = 0; i < itemCount; ++i)
  31. {
  32. list.Add(i);
  33. }
  34. FormattingBufferHelper.ClearThenResetIfTooLarge(list);
  35. return list.Capacity;
  36. }
  37. [Theory]
  38. [MemberData(nameof(SmallSizes))]
  39. public void Should_Keep_Small_Buffer_ArrayBuilder(int itemCount)
  40. {
  41. var capacity = FillAndClearArrayBuilder(itemCount);
  42. Assert.True(capacity >= itemCount);
  43. }
  44. [Theory]
  45. [MemberData(nameof(LargeSizes))]
  46. public void Should_Reset_Large_Buffer_ArrayBuilder(int itemCount)
  47. {
  48. var capacity = FillAndClearArrayBuilder(itemCount);
  49. Assert.Equal(0, capacity);
  50. }
  51. private static int FillAndClearArrayBuilder(int itemCount)
  52. {
  53. var arrayBuilder = new ArrayBuilder<int>();
  54. for (var i = 0; i < itemCount; ++i)
  55. {
  56. arrayBuilder.AddItem(i);
  57. }
  58. FormattingBufferHelper.ClearThenResetIfTooLarge(ref arrayBuilder);
  59. return arrayBuilder.Capacity;
  60. }
  61. [Theory]
  62. [MemberData(nameof(SmallSizes))]
  63. public void Should_Keep_Small_Buffer_Stack(int itemCount)
  64. {
  65. var capacity = FillAndClearStack(itemCount);
  66. Assert.True(capacity >= itemCount);
  67. }
  68. [Theory]
  69. [MemberData(nameof(LargeSizes))]
  70. public void Should_Reset_Large_Buffer_Stack(int itemCount)
  71. {
  72. var capacity = FillAndClearStack(itemCount);
  73. Assert.Equal(0, capacity);
  74. }
  75. private static int FillAndClearStack(int itemCount)
  76. {
  77. var stack = new Stack<int>();
  78. for (var i = 0; i < itemCount; ++i)
  79. {
  80. stack.Push(i);
  81. }
  82. FormattingBufferHelper.ClearThenResetIfTooLarge(stack);
  83. var array = (Array) stack.GetType()
  84. .GetField("_array", BindingFlags.NonPublic | BindingFlags.Instance)!
  85. .GetValue(stack)!;
  86. return array.Length;
  87. }
  88. [Theory]
  89. [MemberData(nameof(SmallSizes))]
  90. public void Should_Keep_Small_Buffer_Dictionary(int itemCount)
  91. {
  92. var capacity = FillAndClearDictionary(itemCount);
  93. Assert.True(capacity >= itemCount);
  94. }
  95. [Theory]
  96. [MemberData(nameof(LargeSizes))]
  97. public void Should_Reset_Large_Buffer_Dictionary(int itemCount)
  98. {
  99. var capacity = FillAndClearDictionary(itemCount);
  100. Assert.True(capacity <= 3); // dictionary trims to the nearest prime starting with 3
  101. }
  102. private static int FillAndClearDictionary(int itemCount)
  103. {
  104. var dictionary = new Dictionary<int, int>();
  105. for (var i = 0; i < itemCount; ++i)
  106. {
  107. dictionary.Add(i, i);
  108. }
  109. FormattingBufferHelper.ClearThenResetIfTooLarge(ref dictionary);
  110. var array = (Array) dictionary.GetType()
  111. .GetField("_entries", BindingFlags.NonPublic | BindingFlags.Instance)!
  112. .GetValue(dictionary)!;
  113. return array.Length;
  114. }
  115. }
  116. }