NodeSystemTests.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System.Reflection;
  2. using Drawie.Backend.Core.Bridge;
  3. using Drawie.Interop.Avalonia.Core;
  4. using Drawie.Interop.VulkanAvalonia;
  5. using Drawie.Skia;
  6. using PixiEditor.ChangeableDocument.Changeables.Graph;
  7. using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
  8. using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
  9. using PixiEditor.ChangeableDocument.Changeables.Interfaces;
  10. using PixiEditor.ChangeableDocument.Changes.NodeGraph;
  11. using PixiEditor.Models.Serialization;
  12. using PixiEditor.Models.Serialization.Factories;
  13. using PixiEditor.Parser.Skia.Encoders;
  14. using Xunit.Abstractions;
  15. namespace PixiEditor.Backend.Tests;
  16. public class NodeSystemTests
  17. {
  18. private readonly ITestOutputHelper output;
  19. private Type[] knownNonSerializableTypes = new[]
  20. {
  21. typeof(Filter),
  22. typeof(Painter)
  23. };
  24. public NodeSystemTests(ITestOutputHelper output)
  25. {
  26. this.output = output;
  27. if (!DrawingBackendApi.HasBackend)
  28. DrawingBackendApi.SetupBackend(new SkiaDrawingBackend(), new AvaloniaRenderingDispatcher());
  29. }
  30. [Fact]
  31. public void TestThatCreateSimpleNodeDoesntThrow()
  32. {
  33. var allNodeTypes = typeof(Node).Assembly.GetTypes()
  34. .Where(x =>
  35. x.IsAssignableTo(typeof(Node))
  36. && x is { IsAbstract: false, IsInterface: false }
  37. && x.GetCustomAttribute<PairNodeAttribute>() == null).ToList();
  38. IReadOnlyDocument target = new MockDocument();
  39. foreach (var type in allNodeTypes)
  40. {
  41. var node = NodeOperations.CreateNode(type, target);
  42. Assert.NotNull(node);
  43. }
  44. }
  45. [Fact]
  46. public void TestThatCreatePairNodeDoesntThrow()
  47. {
  48. var allNodeTypes = typeof(Node).Assembly.GetTypes()
  49. .Where(x =>
  50. x.IsAssignableTo(typeof(Node))
  51. && x is { IsAbstract: false, IsInterface: false }
  52. && x.GetCustomAttribute<PairNodeAttribute>() != null).ToList();
  53. IReadOnlyDocument target = new MockDocument();
  54. Dictionary<Type, Type> pairs = new();
  55. for (var i = 0; i < allNodeTypes.Count; i++)
  56. {
  57. var type = allNodeTypes[i];
  58. var pairAttribute = type.GetCustomAttribute<PairNodeAttribute>();
  59. if (pairAttribute == null) continue;
  60. if (!pairAttribute.IsStartingType) continue;
  61. pairs[type] = pairAttribute.OtherType;
  62. }
  63. foreach (var type in pairs)
  64. {
  65. var startNode = NodeOperations.CreateNode(type.Key, target);
  66. var endNode = NodeOperations.CreateNode(type.Value, target);
  67. Assert.NotNull(startNode);
  68. Assert.NotNull(endNode);
  69. }
  70. }
  71. [Fact]
  72. public void TestThatSerializeNodeDoesntThrow()
  73. {
  74. var allNodeTypes = GetNodeTypesWithoutPairs();
  75. IReadOnlyDocument target = new MockDocument();
  76. foreach (var type in allNodeTypes)
  77. {
  78. var node = NodeOperations.CreateNode(type, target);
  79. Assert.NotNull(node);
  80. Dictionary<string, object> data = new Dictionary<string, object>();
  81. node.SerializeAdditionalData(data);
  82. Assert.NotNull(data);
  83. }
  84. }
  85. [Fact]
  86. private void TestThatAllInputsAreSerializableOrHaveFactories()
  87. {
  88. var allNodeTypes = GetNodeTypesWithoutPairs();
  89. var allFoundFactories = typeof(SerializationFactory).Assembly.GetTypes()
  90. .Where(x => x.IsAssignableTo(typeof(SerializationFactory))
  91. && x is { IsAbstract: false, IsInterface: false }).ToList();
  92. List<SerializationFactory> factories = new();
  93. QoiEncoder encoder = new QoiEncoder();
  94. SerializationConfig config = new SerializationConfig(encoder);
  95. foreach (var factoryType in allFoundFactories)
  96. {
  97. var factory = (SerializationFactory)Activator.CreateInstance(factoryType);
  98. factories.Add(factory);
  99. }
  100. IReadOnlyDocument target = new MockDocument();
  101. foreach (var type in allNodeTypes)
  102. {
  103. var node = NodeOperations.CreateNode(type, target);
  104. Assert.NotNull(node);
  105. foreach (var input in node.InputProperties)
  106. {
  107. if (knownNonSerializableTypes.Contains(input.ValueType)) continue;
  108. if (input.ValueType.IsAbstract) continue;
  109. if (input.ValueType.IsAssignableTo(typeof(Delegate))) continue;
  110. bool hasFactory = factories.Any(x => x.OriginalType == input.ValueType);
  111. Assert.True(
  112. input.ValueType.IsValueType || input.ValueType == typeof(string) || hasFactory,
  113. $"{input.ValueType} doesn't have a factory and is not serializable. Property: {input.InternalPropertyName}, NodeType: {node.GetType().Name}");
  114. }
  115. }
  116. }
  117. [Fact]
  118. public void TestThatAllVectorDataTypesHaveSerializationFactories()
  119. {
  120. var allVectorTypes = typeof(ShapeVectorData).Assembly.GetTypes()
  121. .Where(x => x.IsAssignableTo(typeof(ShapeVectorData))
  122. && x is { IsAbstract: false, IsInterface: false }).ToList();
  123. QoiEncoder encoder = new QoiEncoder();
  124. SerializationConfig config = new SerializationConfig(encoder);
  125. var factoryTypes = typeof(SerializationFactory).Assembly.GetTypes()
  126. .Where(x => x.IsAssignableTo(typeof(SerializationFactory))
  127. && x is { IsAbstract: false, IsInterface: false }).ToList();
  128. List<SerializationFactory> factories = new();
  129. foreach (var factoryType in factoryTypes)
  130. {
  131. var factory = (SerializationFactory)Activator.CreateInstance(factoryType);
  132. factories.Add(factory);
  133. }
  134. foreach (var type in allVectorTypes)
  135. {
  136. bool hasFactory = factories.Any(x => x.OriginalType == type);
  137. Assert.True(hasFactory, $"{type} doesn't have a factory.");
  138. }
  139. }
  140. private static List<Type> GetNodeTypesWithoutPairs()
  141. {
  142. var allNodeTypes = typeof(Node).Assembly.GetTypes()
  143. .Where(x =>
  144. x.IsAssignableTo(typeof(Node))
  145. && x is { IsAbstract: false, IsInterface: false }
  146. && x.GetCustomAttribute<PairNodeAttribute>() == null).ToList();
  147. return allNodeTypes;
  148. }
  149. }