ViewDisposalTest.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using Terminal.Gui;
  6. using Xunit;
  7. using Xunit.Abstractions;
  8. namespace UnitTests.ViewsTests {
  9. public class ViewDisposalTest {
  10. #nullable enable
  11. Dictionary<Type, object? []?> special_params = new Dictionary<Type, object? []?> ();
  12. #nullable restore
  13. readonly ITestOutputHelper output;
  14. public ViewDisposalTest (ITestOutputHelper output)
  15. {
  16. {
  17. this.output = output;
  18. }
  19. }
  20. [Fact]
  21. [AutoInitShutdown]
  22. public void TestViewsDisposeCorrectly ()
  23. {
  24. var reference = DoTest ();
  25. for (var i = 0; i < 10 && reference.IsAlive; i++) {
  26. GC.Collect ();
  27. GC.WaitForPendingFinalizers ();
  28. }
  29. #if DEBUG_IDISPOSABLE
  30. if (reference.IsAlive) {
  31. Assert.True (((View)reference.Target).WasDisposed);
  32. Assert.Fail ($"Some Views didnt get Garbage Collected: {((View)reference.Target).Subviews}");
  33. }
  34. #endif
  35. }
  36. void getSpecialParams ()
  37. {
  38. special_params.Clear ();
  39. //special_params.Add (typeof (LineView), new object [] { Orientation.Horizontal });
  40. }
  41. WeakReference DoTest ()
  42. {
  43. getSpecialParams ();
  44. View Container = new View ();
  45. Toplevel top = Application.Top;
  46. var views = GetViews ();
  47. foreach (var view in views) {
  48. View instance;
  49. //Create instance of view and add to container
  50. if (special_params.ContainsKey (view)) {
  51. instance = (View)Activator.CreateInstance (view, special_params [view]);
  52. } else {
  53. instance = (View)Activator.CreateInstance (view);
  54. }
  55. Assert.NotNull (instance);
  56. Container.Add (instance);
  57. output.WriteLine ($"Added instance of {view}!");
  58. }
  59. top.Add (Container);
  60. // make sure the application is doing to the views whatever its supposed to do to the views
  61. for (var i = 0; i < 100; i++) {
  62. Application.Refresh ();
  63. }
  64. top.Remove (Container);
  65. WeakReference reference = new (Container, true);
  66. Container.Dispose ();
  67. return reference;
  68. }
  69. /// <summary>
  70. /// Get all types derived from <see cref="View"/> using reflection
  71. /// </summary>
  72. /// <returns></returns>
  73. List<Type> GetViews ()
  74. {
  75. List<Type> valid = new ();
  76. // Filter all types that can be instantiated, are public, arent generic, aren't the view type itself, but derive from view
  77. foreach (var type in Assembly.GetAssembly (typeof (View)).GetTypes ().Where (T => { //body of anonymous check function
  78. return ((!T.IsAbstract) && T.IsPublic && T.IsClass && T.IsAssignableTo (typeof (View)) && !T.IsGenericType && !(T == typeof (View)));
  79. })) //end of body of anonymous check function
  80. { //body of the foreach loop
  81. output.WriteLine ($"Found Type {type.Name}");
  82. Assert.DoesNotContain (type, valid);
  83. Assert.True (type.IsAssignableTo (typeof (IDisposable)));// Just to be safe
  84. valid.Add (type);
  85. output.WriteLine (" -Added!");
  86. } //end body of foreach loop
  87. return valid;
  88. }
  89. }
  90. }