ViewDisposalTest.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 (reference.IsAlive) {
  30. Assert.True (((View)reference.Target).WasDisposed);
  31. Assert.Fail ($"Some Views didnt get Garbage Collected: {((View)reference.Target).Subviews}");
  32. }
  33. }
  34. void getSpecialParams ()
  35. {
  36. special_params.Clear ();
  37. //special_params.Add (typeof (LineView), new object [] { Orientation.Horizontal });
  38. }
  39. WeakReference DoTest ()
  40. {
  41. getSpecialParams ();
  42. View Container = new View ();
  43. Toplevel top = Application.Top;
  44. var views = GetViews ();
  45. foreach (var view in views) {
  46. View instance;
  47. //Create instance of view and add to container
  48. if (special_params.ContainsKey (view)) {
  49. instance = (View)Activator.CreateInstance (view, special_params [view]);
  50. } else {
  51. instance = (View)Activator.CreateInstance (view);
  52. }
  53. Assert.NotNull (instance);
  54. Container.Add (instance);
  55. output.WriteLine ($"Added instance of {view}!");
  56. }
  57. top.Add (Container);
  58. // make sure the application is doing to the views whatever its supposed to do to the views
  59. for (var i = 0; i < 100; i++) {
  60. Application.Refresh ();
  61. }
  62. top.Remove (Container);
  63. WeakReference reference = new (Container, true);
  64. Container.Dispose ();
  65. return reference;
  66. }
  67. /// <summary>
  68. /// Get all types derived from <see cref="View"/> using reflection
  69. /// </summary>
  70. /// <returns></returns>
  71. List<Type> GetViews ()
  72. {
  73. List<Type> valid = new ();
  74. // Filter all types that can be instantiated, are public, arent generic, aren't the view type itself, but derive from view
  75. foreach (var type in Assembly.GetAssembly (typeof (View)).GetTypes ().Where (T => { //body of anonymous check function
  76. return ((!T.IsAbstract) && T.IsPublic && T.IsClass && T.IsAssignableTo (typeof (View)) && !T.IsGenericType && !(T == typeof (View)));
  77. })) //end of body of anonymous check function
  78. { //body of the foreach loop
  79. output.WriteLine ($"Found Type {type.Name}");
  80. Assert.DoesNotContain (type, valid);
  81. Assert.True (type.IsAssignableTo (typeof (IDisposable)));// Just to be safe
  82. valid.Add (type);
  83. output.WriteLine (" -Added!");
  84. } //end body of foreach loop
  85. return valid;
  86. }
  87. }
  88. }