public void Calculate_WithValidArgumentsAndResult_ReturnsExpectedOutput()
        {
            // Setup
            var    random                    = new Random(21);
            int    nrOfFailedEngines         = random.Next();
            double density                   = random.NextDouble();
            double gravitationalAcceleration = random.NextDouble();

            var calculation = new BalancedFieldLengthCalculation();

            SetValidAircraftData(calculation.AircraftData);
            SetEngineData(calculation.EngineData);
            SetSimulationSettingsData(calculation.SimulationSettings);

            calculation.SimulationSettings.Density = density;
            calculation.SimulationSettings.GravitationalAcceleration = gravitationalAcceleration;
            calculation.SimulationSettings.EndFailureVelocity        = 3;

            calculation.EngineData.NrOfFailedEngines = nrOfFailedEngines;

            const double expectedVelocity = 11;
            const double expectedDistance = 20;
            var          outputs          = new[]
            {
                new AggregatedDistanceOutput(10, 10, 30),
                new AggregatedDistanceOutput(expectedVelocity, expectedDistance, 20),
                new AggregatedDistanceOutput(12, 30, 10)
            };

            var kernel = Substitute.For <IAggregatedDistanceCalculatorKernel>();

            kernel.Calculate(Arg.Any <KernelAircraftData>(),
                             Arg.Any <EulerIntegrator>(),
                             Arg.Any <int>(),
                             Arg.Any <double>(),
                             Arg.Any <double>(),
                             Arg.Any <CalculationSettings>())
            .Returns(outputs[0], outputs[1], outputs[2]);

            var testFactory = new TestKernelFactory(kernel);

            using (new BalancedFieldLengthKernelFactoryConfig(testFactory))
            {
                var module = new BalancedFieldLengthCalculationModule();

                // Call
                BalancedFieldLengthOutput output = module.Calculate(calculation);

                // Assert
                Assert.That(output.Velocity, Is.EqualTo(expectedVelocity));
                Assert.That(output.Distance, Is.EqualTo(expectedDistance));

                ICall[] calls = kernel.ReceivedCalls().ToArray();
                Assert.That(calls.Length, Is.EqualTo(3));
                AssertCalculateCall(calls[0], calculation, 0);
                AssertCalculateCall(calls[1], calculation, 1);
                AssertCalculateCall(calls[2], calculation, 2);
            }
        }
        public void Calculate_CalculationNull_ThrowsArgumentNullException()
        {
            // Setup
            var module = new BalancedFieldLengthCalculationModule();

            // Call
            TestDelegate call = () => module.Calculate(null);

            // Assert
            Assert.That(call, Throws.TypeOf <ArgumentNullException>()
                        .With.Property(nameof(ArgumentNullException.ParamName))
                        .EqualTo("calculation"));
        }
        public void Calculate_CalculatorThrowsCalculateException_ThrowsKernelCalculateException()
        {
            // Setup
            var calculation = new BalancedFieldLengthCalculation();

            SetValidAircraftData(calculation.AircraftData);
            SetEngineData(calculation.EngineData);
            SetSimulationSettingsData(calculation.SimulationSettings);

            calculation.SimulationSettings.EndFailureVelocity = 1;

            var kernel = Substitute.For <IAggregatedDistanceCalculatorKernel>();
            var calculatorException = new CalculatorException("Can't calculate this.");

            kernel.Calculate(Arg.Any <KernelAircraftData>(),
                             Arg.Any <EulerIntegrator>(),
                             Arg.Any <int>(),
                             Arg.Any <double>(),
                             Arg.Any <double>(),
                             Arg.Any <CalculationSettings>())
            .ThrowsForAnyArgs(calculatorException);

            var testFactory = new TestKernelFactory(kernel);

            using (new BalancedFieldLengthKernelFactoryConfig(testFactory))
            {
                var module = new BalancedFieldLengthCalculationModule();

                // Call
                TestDelegate call = () => module.Calculate(calculation);

                // Assert
                var exception = Assert.Throws <KernelCalculationException>(call);
                Assert.That(exception.InnerException, Is.SameAs(calculatorException));
                Assert.That(exception.Message, Is.EqualTo(calculatorException.Message));
            }
        }