NodeSystemTests.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using System.Reflection;
  2. using Drawie.Backend.Core.Bridge;
  3. using Drawie.Backend.Core.Surfaces.ImageData;
  4. using Drawie.Interop.Avalonia.Core;
  5. using Drawie.Interop.VulkanAvalonia;
  6. using Drawie.Skia;
  7. using PixiEditor.ChangeableDocument.Changeables.Graph;
  8. using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
  9. using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes.Shapes.Data;
  10. using PixiEditor.ChangeableDocument.Changeables.Interfaces;
  11. using PixiEditor.ChangeableDocument.Changes.NodeGraph;
  12. using PixiEditor.Models.Serialization;
  13. using PixiEditor.Models.Serialization.Factories;
  14. using PixiEditor.Parser.Skia.Encoders;
  15. using PixiEditor.Tests;
  16. using Xunit.Abstractions;
  17. namespace PixiEditor.Backend.Tests;
  18. public class NodeSystemTests : PixiEditorTest
  19. {
  20. private readonly ITestOutputHelper output;
  21. private Type[] knownNonSerializableTypes = new[]
  22. {
  23. typeof(Filter),
  24. typeof(Painter)
  25. };
  26. public NodeSystemTests(ITestOutputHelper output)
  27. {
  28. this.output = output;
  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, ColorSpace.CreateSrgbLinear());
  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.IsPrimitive || input.ValueType.IsEnum || input.ValueType == typeof(string) ||
  113. hasFactory,
  114. $"{input.ValueType} doesn't have a factory and is not serializable. Property: {input.InternalPropertyName}, NodeType: {node.GetType().Name}");
  115. }
  116. }
  117. }
  118. [Fact]
  119. public void TestThatAllVectorDataTypesHaveSerializationFactories()
  120. {
  121. var allVectorTypes = typeof(ShapeVectorData).Assembly.GetTypes()
  122. .Where(x => x.IsAssignableTo(typeof(ShapeVectorData))
  123. && x is { IsAbstract: false, IsInterface: false }).ToList();
  124. QoiEncoder encoder = new QoiEncoder();
  125. SerializationConfig config = new SerializationConfig(encoder, ColorSpace.CreateSrgbLinear());
  126. var factoryTypes = typeof(SerializationFactory).Assembly.GetTypes()
  127. .Where(x => x.IsAssignableTo(typeof(SerializationFactory))
  128. && x is { IsAbstract: false, IsInterface: false }).ToList();
  129. List<SerializationFactory> factories = new();
  130. foreach (var factoryType in factoryTypes)
  131. {
  132. var factory = (SerializationFactory)Activator.CreateInstance(factoryType);
  133. factories.Add(factory);
  134. }
  135. foreach (var type in allVectorTypes)
  136. {
  137. bool hasFactory = factories.Any(x => x.OriginalType == type);
  138. Assert.True(hasFactory, $"{type} doesn't have a factory.");
  139. }
  140. }
  141. [Fact]
  142. public void TestThatSerializationFactoriesIdsAreNotDuplicated()
  143. {
  144. var factoryTypes = typeof(SerializationFactory).Assembly.GetTypes()
  145. .Where(x => x.IsAssignableTo(typeof(SerializationFactory))
  146. && x is { IsAbstract: false, IsInterface: false }).ToList();
  147. List<SerializationFactory> factories = new();
  148. foreach (var factoryType in factoryTypes)
  149. {
  150. var factory = (SerializationFactory)Activator.CreateInstance(factoryType);
  151. factories.Add(factory);
  152. }
  153. List<string> ids = new();
  154. foreach (var factory in factories)
  155. {
  156. Assert.DoesNotContain(factory.DeserializationId, ids);
  157. ids.Add(factory.DeserializationId);
  158. }
  159. }
  160. private static List<Type> GetNodeTypesWithoutPairs()
  161. {
  162. var allNodeTypes = typeof(Node).Assembly.GetTypes()
  163. .Where(x =>
  164. x.IsAssignableTo(typeof(Node))
  165. && x is { IsAbstract: false, IsInterface: false }
  166. && x.GetCustomAttribute<PairNodeAttribute>() == null).ToList();
  167. return allNodeTypes;
  168. }
  169. }