| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 | using System.Collections.Immutable;using System.Reflection;using ChunkyImageLib;using ChunkyImageLib.DataHolders;using PixiEditor.AvaloniaUI.Helpers;using PixiEditor.AvaloniaUI.Models.Serialization;using PixiEditor.AvaloniaUI.Models.Serialization.Factories;using PixiEditor.ChangeableDocument.Changeables.Animations;using PixiEditor.ChangeableDocument.Changeables.Graph;using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;using PixiEditor.ChangeableDocument.Changeables.Interfaces;using PixiEditor.ChangeableDocument.Changes.NodeGraph;using PixiEditor.ChangeableDocument.Rendering;using PixiEditor.DrawingApi.Core.Bridge;using PixiEditor.DrawingApi.Skia;using PixiEditor.Numerics;using PixiEditor.Parser.Skia.Encoders;using Xunit.Abstractions;using Xunit.Sdk;namespace PixiEditor.Backend.Tests;public class NodeSystemTests{    private readonly ITestOutputHelper output;    private Type[] knownNonSerializableTypes = new[]    {        typeof(Filter)    };    public NodeSystemTests(ITestOutputHelper output)    {        this.output = output;        if (!DrawingBackendApi.HasBackend)            DrawingBackendApi.SetupBackend(new SkiaDrawingBackend());    }    [Fact]    public void TestThatNodeGraphExecutesEmptyOutputNode()    {        NodeGraph graph = new NodeGraph();        OutputNode outputNode = new OutputNode();        graph.AddNode(outputNode);        using RenderingContext context = new RenderingContext(0, VecI.Zero, ChunkResolution.Full, new VecI(1, 1));        graph.Execute(context);        Assert.Null(outputNode.CachedResult);    }    [Fact]    public void TestThatCreateSimpleNodeDoesntThrow()    {        var allNodeTypes = typeof(Node).Assembly.GetTypes()            .Where(x =>                x.IsAssignableTo(typeof(Node))                && x is { IsAbstract: false, IsInterface: false }                && x.GetCustomAttribute<PairNodeAttribute>() == null).ToList();        IReadOnlyDocument target = new MockDocument();        foreach (var type in allNodeTypes)        {            var node = NodeOperations.CreateNode(type, target);            Assert.NotNull(node);        }    }    [Fact]    public void TestThatCreatePairNodeDoesntThrow()    {        var allNodeTypes = typeof(Node).Assembly.GetTypes()            .Where(x =>                x.IsAssignableTo(typeof(Node))                && x is { IsAbstract: false, IsInterface: false }                && x.GetCustomAttribute<PairNodeAttribute>() != null).ToList();        IReadOnlyDocument target = new MockDocument();        Dictionary<Type, Type> pairs = new();        for (var i = 0; i < allNodeTypes.Count; i++)        {            var type = allNodeTypes[i];            var pairAttribute = type.GetCustomAttribute<PairNodeAttribute>();            if (pairAttribute == null) continue;            if (!pairAttribute.IsStartingType) continue;            pairs[type] = pairAttribute.OtherType;        }        foreach (var type in pairs)        {            var startNode = NodeOperations.CreateNode(type.Key, target);            var endNode = NodeOperations.CreateNode(type.Value, target, startNode);            Assert.NotNull(startNode);            Assert.NotNull(endNode);        }    }    [Fact]    public void TestThatSerializeNodeDoesntThrow()    {        var allNodeTypes = GetNodeTypesWithoutPairs();        IReadOnlyDocument target = new MockDocument();        foreach (var type in allNodeTypes)        {            var node = NodeOperations.CreateNode(type, target);            Assert.NotNull(node);            Dictionary<string, object> data = new Dictionary<string, object>();            node.SerializeAdditionalData(data);            Assert.NotNull(data);        }    }    [Fact]    private void TestThatAllInputsAreSerializableOrHaveFactories()    {        var allNodeTypes = GetNodeTypesWithoutPairs();        var allFoundFactories = typeof(SerializationFactory).Assembly.GetTypes()            .Where(x => x.IsAssignableTo(typeof(SerializationFactory))                        && x is { IsAbstract: false, IsInterface: false }).ToList();                List<SerializationFactory> factories = new();        QoiEncoder encoder = new QoiEncoder();        SerializationConfig config = new SerializationConfig(encoder);                foreach (var factoryType in allFoundFactories)        {            var factory = (SerializationFactory)Activator.CreateInstance(factoryType);            factories.Add(factory);        }        IReadOnlyDocument target = new MockDocument();        foreach (var type in allNodeTypes)        {            var node = NodeOperations.CreateNode(type, target);            Assert.NotNull(node);            foreach (var input in node.InputProperties)            {                if (knownNonSerializableTypes.Contains(input.ValueType)) continue;                if (input.ValueType.IsAssignableTo(typeof(Delegate))) continue;                bool hasFactory = factories.Any(x => x.OriginalType == input.ValueType);                Assert.True(                    input.ValueType.IsValueType || input.ValueType == typeof(string) || hasFactory,                     $"{input.ValueType} doesn't have a factory and is not serializable. Property: {input.InternalPropertyName}, NodeType: {node.GetType().Name}");            }        }    }    private static List<Type> GetNodeTypesWithoutPairs()    {        var allNodeTypes = typeof(Node).Assembly.GetTypes()            .Where(x =>                x.IsAssignableTo(typeof(Node))                && x is { IsAbstract: false, IsInterface: false }                && x.GetCustomAttribute<PairNodeAttribute>() == null).ToList();        return allNodeTypes;    }}
 |