public void Pipeline_BindArgumentToPipelineInput_By_Bad_Name_Throws()
        {
            MockProcessor1 processor = new MockProcessor1();
            MockPipeline pipeline = new MockPipeline(
                new Processor[] { processor },
                new ProcessorArgument[] { new ProcessorArgument("PipelineInput", typeof(int)) },
                Enumerable.Empty<ProcessorArgument>());

            ExceptionAssert.Throws(
                typeof(ArgumentException),
                "BindArgumentToPipelineInput should throw with null name",
                () => pipeline.BindArgumentToPipelineInput(null, processor.InArguments[0]),
                "pipelineInputArgumentName"
                );

            ExceptionAssert.Throws(
                typeof(ArgumentException),
                "BindArgumentToPipelineInput should throw with empty name",
                () => pipeline.BindArgumentToPipelineInput(string.Empty, processor.InArguments[0]),
                "pipelineInputArgumentName"
                );

            ExceptionAssert.Throws(
                typeof(ArgumentException),
                "BindArgumentToPipelineInput should throw with whitespace name",
                () => pipeline.BindArgumentToPipelineInput("   ", processor.InArguments[0]),
                "pipelineInputArgumentName"
                );

            ExceptionAssert.ThrowsInvalidOperation(
                "BindArgumentToPipelineInput should throw with non-existent name",
                () => pipeline.BindArgumentToPipelineInput("NotAName", processor.InArguments[0])
                );
        }
        /// <summary>
        /// This pipeline has 2 MockProcessor1's in it, both binding their inputs to the pipeline's 'intValue'.
        /// The pipeline has 2 outputs, one bound to each processor's.
        /// </summary>
        /// <returns></returns>
        public static MockPipeline CreateDoubleMockProcessor1Pipeline()
        {
            Processor processor1 = new MockProcessor1();
            Processor processor2 = new MockProcessor1();
            MockPipeline pipeline = new MockPipeline(
                                    new[] { processor1, processor2 },
                                    new[] { new ProcessorArgument("intValue", typeof(int), new object[0]) },
                                    new[] { new ProcessorArgument("theResult1", typeof(string), new object[0]),
                                            new ProcessorArgument("theResult2", typeof(string), new object[0])}
                                    );

            // Pipeline["intValue"] --> Processor1[0]
            pipeline.BindArgumentToPipelineInput("intValue", processor1.InArguments[0]);

            // Pipeline["intValue"] --> Processor2[0]
            pipeline.BindArgumentToPipelineInput("intValue", processor2.InArguments[0]);

            // Processor1[0] --> Pipeline["theResult1"]
            pipeline.BindArgumentToPipelineOutput(processor1.OutArguments[0], "theResult1");

            // Processor2[0] --> Pipeline["theResult2"]
            pipeline.BindArgumentToPipelineOutput(processor2.OutArguments[0], "theResult2");
            pipeline.Initialize();
            return pipeline;
        }
        /// <summary>
        /// Creates a Pipeline with no actual processor other than binding the pipeline inputs to the
        /// pipeline outputs. 
        /// </summary>
        /// <returns></returns>
        public static MockPipeline CreateEmptyPipeline()
        {
            MockPipeline pipeline = new MockPipeline(
                                    new Processor[0],
                                    new[] { new ProcessorArgument("inValue", typeof(string), new object[0]) },
                                    new[] { new ProcessorArgument("outValue", typeof(string), new object[0]) }
                                    );

            pipeline.BindArgumentToPipelineInput("inValue", pipeline.Processors[1].InArguments[0]);
            pipeline.Initialize();
            return pipeline;
        }
        /// <summary>
        /// Creates an uninitialized Pipeline with a single MockProcessor1 in it, binding its inputs to the pipeline inputs
        /// and its outputs to the pipeline outputs.
        /// </summary>
        /// <returns></returns>
        public static MockPipeline CreateMockProcessor1PipelineUninitialized()
        {
            Processor processor = new MockProcessor1();
            MockPipeline pipeline = new MockPipeline(
                                    new[] { processor },
                                    new[] { new ProcessorArgument("intValue", typeof(int), new object[0]) },
                                    new[] { new ProcessorArgument("theResult", typeof(string), new object[0]) }
                                    );

            pipeline.BindArgumentToPipelineInput("intValue", processor.InArguments[0]);
            pipeline.BindArgumentToPipelineOutput(processor.OutArguments[0], "theResult");
            return pipeline;
        }
        public void Pipeline_BindArgumentToPipelineInput_By_Bad_Index_Throws()
        {
            MockProcessor1 processor = new MockProcessor1();
            MockPipeline pipeline = new MockPipeline(
                new Processor[] { processor },
                new ProcessorArgument[] { new ProcessorArgument("PipelineInput", typeof(int)) },
                Enumerable.Empty<ProcessorArgument>());

            ExceptionAssert.Throws(
                typeof(ArgumentOutOfRangeException),
                "BindArgumentToPipelineInput should throw with negative index",
                () => pipeline.BindArgumentToPipelineInput(-1, processor.InArguments[0]),
                "pipelineInputArgumentIndex"
                );

            ExceptionAssert.Throws(
                typeof(ArgumentOutOfRangeException),
                "BindArgumentToPipelineInput should throw with too large an index",
                () => pipeline.BindArgumentToPipelineInput(1, processor.InArguments[0]),
                "pipelineInputArgumentIndex"
                );
        }
        public void Pipeline_Executes_With_No_Bindings_To_Pipeline()
        {
            MockProcessor1 processor1 = new MockProcessor1();
            MockProcessorEchoString processor2 = new MockProcessorEchoString();
            MockPipeline pipeline = new MockPipeline(
                                        new Processor[] { processor1, processor2 },
                                        Enumerable.Empty<ProcessorArgument>(),
                                        Enumerable.Empty<ProcessorArgument>());
            pipeline.BindArguments(processor1.OutArguments[0], processor2.InArguments[0]);
            pipeline.Initialize();
            ProcessorResult result = pipeline.Execute(new object[0]);
            Assert.IsNotNull(result, "Expected non-null ProcessorResult");
            Assert.IsNotNull(result.Output, "Expected non-null output from unbound pipeline");
            Assert.AreEqual(0, result.Output.Length, "Expected empty array from unbound pipeline");

            // Verify processor1 pushed default(int) through to processor2
            object value = pipeline.Context.ReadInput(processor2.InArguments[0]);
            Assert.IsNotNull(value);
            Assert.AreEqual(default(int).ToString(), value, "Expected default(int) to be passed from processor1 to processor2");
        }
 public void Pipeline_Executes_With_No_Bindings()
 {
     MockProcessor1 processor1 = new MockProcessor1();
     MockProcessorEchoString processor2 = new MockProcessorEchoString();
     MockPipeline pipeline = new MockPipeline(
                                 new Processor[] { processor1, processor2 },
                                 Enumerable.Empty<ProcessorArgument>(),
                                 Enumerable.Empty<ProcessorArgument>());
     pipeline.Initialize();
     ProcessorResult result = pipeline.Execute(new object[0]);
     Assert.IsNotNull(result, "Expected non-null ProcessorResult");
     Assert.IsNotNull(result.Output, "Expected non-null output from unbound pipeline");
     Assert.AreEqual(0, result.Output.Length, "Expected empty array from unbound pipeline");
     Assert.AreEqual(ProcessorStatus.Ok, result.Status, "Expected OK status from pipeline");
 }
        public void Pipeline_BindArgumentToPipelineInput_By_Index()
        {
            MockProcessor1 processor = new MockProcessor1();
            MockPipeline pipeline = new MockPipeline(
                new Processor[] { processor },
                new ProcessorArgument[] { new ProcessorArgument("PipelineInput", typeof(int)) },
                Enumerable.Empty<ProcessorArgument>());

            BindArgumentsEventArgs eventArgs = null;
            ProcessorArgument inArgFromBind = null;
            ProcessorArgument outArgFromBind = null;

            pipeline.OnBindArgumentsCalled = (outArg, inArg) =>
                {
                    inArgFromBind = inArg;
                    outArgFromBind = outArg;
                };

            pipeline.BoundArguments = (s, a) => { eventArgs = a as BindArgumentsEventArgs; };
            pipeline.BindArgumentToPipelineInput(0, processor.InArguments[0]);
            Assert.IsNotNull(eventArgs, "Did not receive OnBoundArguments callback");
            Assert.AreSame(pipeline.Processors[0].OutArguments[0], outArgFromBind, "Did not receive correct outArg in OnBind virtual");
            Assert.AreSame(pipeline.Processors[1].InArguments[0], inArgFromBind, "Did not receive correct inArg in OnBind virtual");
            Assert.IsTrue(pipeline.GetBoundToArguments(pipeline.Processors[0].OutArguments[0]).Contains(processor.InArguments[0]),
                            "Failed to find processor 1's in argument in bindings for entry processor");
        }
        public void Pipeline_Bind_OnBinding_OnBind_OnBound_Callbacks()
        {
            MockProcessor1 processor1 = new MockProcessor1();
            MockProcessorEchoString processor2 = new MockProcessorEchoString();
            MockPipeline pipeline = new MockPipeline(
                new Processor[] { processor1, processor2 },
                Enumerable.Empty<ProcessorArgument>(),
                Enumerable.Empty<ProcessorArgument>());
            BindArgumentsEventArgs bindingEventArgs = null;
            BindArgumentsEventArgs boundEventArgs = null;
            ProcessorArgument inArgFromBind = null;
            ProcessorArgument outArgFromBind = null;

            pipeline.OnBindArgumentsCalled = (outArg, inArg) =>
            {
                inArgFromBind = inArg;
                outArgFromBind = outArg;
            };

            pipeline.BindingArguments = (s, a) => { bindingEventArgs = a as BindArgumentsEventArgs; };
            pipeline.BoundArguments = (s, a) => { boundEventArgs = a as BindArgumentsEventArgs; };

            pipeline.BindArguments(processor1.OutArguments[0], processor2.InArguments[0]);
            Assert.IsNotNull(bindingEventArgs, "Did not receive BindingArguments callback");
            Assert.AreSame(processor1.OutArguments[0], bindingEventArgs.OutArgument, "Did not receive correct outArg in BindingArgument callback");
            Assert.AreSame(processor2.InArguments[0], bindingEventArgs.InArgument, "Did not receive correct inArg in BindingArgument callback");

            Assert.IsNotNull(boundEventArgs, "Did not receive BoundArguments callback");
            Assert.AreSame(processor1.OutArguments[0], boundEventArgs.OutArgument, "Did not receive correct outArg in BoundArgument callback");
            Assert.AreSame(processor2.InArguments[0], boundEventArgs.InArgument, "Did not receive correct inArg in BoundArgument callback");

            Assert.AreSame(processor1.OutArguments[0], outArgFromBind, "Did not receive correct outArg in OnBind virtual");
            Assert.AreSame(processor2.InArguments[0], inArgFromBind, "Did not receive correct inArg in OnBind virtual");
        }