public void TestBasicInputOutputRelation()
 {
     var delay1 = new DelayStep();
     var delay2 = new DelayStep();
     {
         var member = TypeData.GetTypeData(delay1).GetMember(nameof(DelayStep.DelaySecs));
         InputOutputRelation.Assign(delay2, member, delay1, member);
     }
     {
         double testValue = 10;
         delay1.DelaySecs = testValue;
         delay2.DelaySecs = 0;
         InputOutputRelation.UpdateInputs(delay2);
         Assert.AreEqual(delay1.DelaySecs, delay2.DelaySecs);
         Assert.AreEqual(testValue, delay1.DelaySecs);
     }
     {
         var member = TypeData.GetTypeData(delay1).GetMember(nameof(DelayStep.DelaySecs));
         InputOutputRelation.Unassign(delay2, member, delay1, member);
     }
     {
         double testValue = 10;
         delay1.DelaySecs = testValue;
         delay2.DelaySecs = 0;
         InputOutputRelation.UpdateInputs(delay2);
         Assert.AreNotEqual(delay1.DelaySecs, delay2.DelaySecs);
         Assert.AreEqual(testValue, delay1.DelaySecs);
     }
 }
        public override bool Serialize(XElement node, object obj, ITypeData expectedType)
        {
            if (obj is ITestStepParent step && activeElements.Contains(node) == false)
            {
                activeElements.Add(node);
                try
                {
                    var inputs = InputOutputRelation.GetRelations(step).Where(x => x.InputObject == step).ToArray();
                    if (inputs.Length == 0)
                    {
                        return(false);
                    }
                    var items = inputs.Select(x => new InputOutputMember
                    {
                        Id = (x.OutputObject as ITestStep)?.Id ?? Guid.Empty, Member = x.OutputMember.Name, TargetMember = x.InputMember.Name
                    }).ToArray();
                    var subnode = new XElement(stepInputsName);
                    Serializer.Serialize(subnode, items, TypeData.GetTypeData(items));
                    var ok = Serializer.Serialize(node, obj, expectedType);
                    if (ok)
                    {
                        node.Add(subnode);
                    }
                    return(ok);
                }
                finally
                {
                    activeElements.Remove(node);
                }
            }

            return(false);
        }
        public void TestMultipleOutputFromTheSameProperty()
        {
            var a            = new OutputInput();
            var b            = new OutputInput();
            var inputMember  = TypeData.GetTypeData(a).GetMember(nameof(a.Input));
            var outputMember = TypeData.GetTypeData(b).GetMember(nameof(b.Output));
            var inputMember2 = TypeData.GetTypeData(a).GetMember(nameof(a.ExpectedInput));

            InputOutputRelation.Assign(a, inputMember, b, outputMember);
            InputOutputRelation.Assign(a, inputMember2, b, outputMember);

            Assert.IsTrue(InputOutputRelation.IsInput(a, inputMember));
            Assert.IsTrue(InputOutputRelation.IsInput(a, inputMember2));
            Assert.Throws <ArgumentException>(() => InputOutputRelation.Assign(a, inputMember, b, outputMember));
            Assert.Throws <ArgumentException>(() => InputOutputRelation.Assign(a, inputMember2, b, outputMember));
        }
        public void TestAutoRemoveInputOutputRelation()
        {
            var plan   = new TestPlan();
            var delay1 = new DelayStep();
            var delay2 = new DelayStep();

            plan.ChildTestSteps.Add(delay1);
            plan.ChildTestSteps.Add(delay2);
            {
                var member = TypeData.GetTypeData(delay1).GetMember(nameof(DelayStep.DelaySecs));
                InputOutputRelation.Assign(delay2, member, delay1, member);
                Assert.IsTrue(InputOutputRelation.IsInput(delay2, member));
                Assert.IsTrue(InputOutputRelation.IsOutput(delay1, member));
            }
            plan.ChildTestSteps.Remove(delay2);
            {
                var member = TypeData.GetTypeData(delay1).GetMember(nameof(DelayStep.DelaySecs));
                Assert.IsFalse(InputOutputRelation.IsInput(delay2, member));
                Assert.IsFalse(InputOutputRelation.IsOutput(delay1, member));
            }
        }
        public void TestSerializeReadOnlyMemberInputOutput()
        {
            var plan = new TestPlan();
            var a    = new ReadOnlyMemberOutput();
            var b    = new ReadOnlyMemberOutput();

            plan.ChildTestSteps.Add(a);
            plan.ChildTestSteps.Add(b);
            var readonlyMember = TypeData.GetTypeData(a).GetMember(nameof(a.X));
            var writableMember = TypeData.GetTypeData(a).GetMember(nameof(a.Y));

            InputOutputRelation.Assign(b, writableMember, a, readonlyMember);
            Assert.IsTrue(InputOutputRelation.IsOutput(a, readonlyMember));
            Assert.IsTrue(InputOutputRelation.IsInput(b, writableMember));

            var xml = plan.SerializeToString();

            plan = Utils.DeserializeFromString <TestPlan>(xml);
            a    = (ReadOnlyMemberOutput)plan.ChildTestSteps[0];
            b    = (ReadOnlyMemberOutput)plan.ChildTestSteps[1];
            Assert.IsTrue(InputOutputRelation.IsOutput(a, readonlyMember));
            Assert.IsTrue(InputOutputRelation.IsInput(b, writableMember));
        }
        public void TestSerializingConnectionsBetweenSteps()
        {
            var step1 = new OutputInput {
                Output = 5, Input = 5, Name = "Step 1"
            };
            var step2 = new OutputInput {
                ExpectedInput = 5, CheckExpectedInput = true, Name = "Step 2"
            };
            var step3 = new OutputInput {
                ExpectedInput = 5, CheckExpectedInput = true, Name = "Step 3"
            };
            var plan = new TestPlan();

            plan.ChildTestSteps.AddRange(new [] { step1, step2, step3 });
            var outputMember = TypeData.GetTypeData(step1).GetMember(nameof(OutputInput.Output));
            var inputMember  = TypeData.GetTypeData(step1).GetMember(nameof(OutputInput.Input));

            InputOutputRelation.Assign(step2, inputMember, step1, outputMember);
            InputOutputRelation.Assign(step3, inputMember, step2, outputMember);

            var xml = plan.SerializeToString();

            var plan2 = Utils.DeserializeFromString <TestPlan>(xml);

            step1 = (OutputInput)plan2.Steps[0];
            step2 = (OutputInput)plan2.Steps[1];
            step3 = (OutputInput)plan2.Steps[2];
            Assert.IsTrue(InputOutputRelation.IsOutput(step1, outputMember));
            Assert.IsFalse(InputOutputRelation.IsInput(step1, outputMember));
            Assert.IsFalse(InputOutputRelation.IsOutput(step1, inputMember));
            Assert.IsFalse(InputOutputRelation.IsInput(step1, inputMember));

            Assert.IsTrue(InputOutputRelation.IsInput(step2, inputMember));
            Assert.IsTrue(InputOutputRelation.IsOutput(step2, outputMember));
            Assert.IsTrue(InputOutputRelation.IsInput(step3, inputMember));
            Assert.IsFalse(InputOutputRelation.IsOutput(step3, outputMember));
        }
        public void TestInputOutputRelationsInTestPlan()
        {
            var step1 = new OutputInput {
                Output = 5, Input = 5, Name = "Step 1"
            };
            var step2 = new OutputInput {
                ExpectedInput = 5, CheckExpectedInput = true, Name = "Step 2"
            };
            var step3 = new OutputInput {
                ExpectedInput = 5, CheckExpectedInput = true, Name = "Step 3"
            };
            var plan = new TestPlan();

            plan.ChildTestSteps.AddRange(new [] { step1, step2, step3 });
            {
                var outputMember = TypeData.GetTypeData(step1).GetMember(nameof(OutputInput.Output));
                var inputMember  = TypeData.GetTypeData(step1).GetMember(nameof(OutputInput.Input));
                InputOutputRelation.Assign(step2, inputMember, step1, outputMember);
                InputOutputRelation.Assign(step3, inputMember, step2, outputMember);

                Assert.IsTrue(InputOutputRelation.IsOutput(step1, outputMember));
                Assert.IsFalse(InputOutputRelation.IsInput(step1, outputMember));
                Assert.IsFalse(InputOutputRelation.IsOutput(step1, inputMember));
                Assert.IsFalse(InputOutputRelation.IsInput(step1, inputMember));

                Assert.IsTrue(InputOutputRelation.IsInput(step2, inputMember));
                Assert.IsTrue(InputOutputRelation.IsOutput(step2, outputMember));
                Assert.IsTrue(InputOutputRelation.IsInput(step3, inputMember));
                Assert.IsFalse(InputOutputRelation.IsOutput(step3, outputMember));
            }

            {
                var run = plan.Execute();
                Assert.AreEqual(Verdict.Pass, run.Verdict);
            }
        }
        public override bool Deserialize(XElement node, ITypeData t, Action <object> setter)
        {
            if (t.DescendsTo(typeof(ITestStepParent)) == false)
            {
                return(false);
            }
            if (node.Element(stepInputsName) is XElement subelems && activeElements.Contains(node) == false)
            {
                var             tps        = Serializer.GetSerializer <TestPlanSerializer>();
                ITestStepParent step       = null;
                var             prevsetter = setter;
                setter = x => prevsetter(step = x as ITestStepParent);
                var plan = tps.Plan;
                InputOutputMember[] items = null;
                if (tps != null && Serializer.Deserialize(subelems, x => items = (InputOutputMember[])x, TypeData.FromType(typeof(InputOutputMember[]))))
                {
                    bool ok = false;
                    activeElements.Add(node);
                    try
                    {
                        ok = Serializer.Deserialize(node, setter, t);
                    }
                    catch
                    {
                        activeElements.Remove(node);
                    }


                    void connectInputs()
                    {
                        if (step == null)
                        {
                            return;
                        }
                        foreach (var elem in items)
                        {
                            ITestStepParent source;
                            if (elem.Id == Guid.Empty)
                            {
                                source = plan;
                            }
                            else
                            {
                                source = plan.ChildTestSteps.GetStep(elem.Id);
                            }
                            var sourceType   = TypeData.GetTypeData(source);
                            var targetType   = TypeData.GetTypeData(step);
                            var sourceMember = sourceType.GetMember(elem.Member);
                            var targetMember = targetType.GetMember(elem.TargetMember);
                            if (sourceMember != null && targetMember != null)
                            {
                                InputOutputRelation.Assign(step, targetMember, source, sourceMember);
                            }
                        }
                    }

                    if (ok)
                    {
                        Serializer.DeferLoad(connectInputs);
                    }
                    return(ok);
                }
            }

            return(false);
        }