Index: Riskeer/Common/src/Riskeer.Common.Data/AssemblyTool/FailureMechanismSectionAssemblyGroupFactory.cs =================================================================== diff -u -rc292d279a83c6a04d7020f53fff8a2ad99c68b48 -rb4f2bb1d7e6a8e2028af63b32a6f2ea3d9b6e24e --- Riskeer/Common/src/Riskeer.Common.Data/AssemblyTool/FailureMechanismSectionAssemblyGroupFactory.cs (.../FailureMechanismSectionAssemblyGroupFactory.cs) (revision c292d279a83c6a04d7020f53fff8a2ad99c68b48) +++ Riskeer/Common/src/Riskeer.Common.Data/AssemblyTool/FailureMechanismSectionAssemblyGroupFactory.cs (.../FailureMechanismSectionAssemblyGroupFactory.cs) (revision b4f2bb1d7e6a8e2028af63b32a6f2ea3d9b6e24e) @@ -79,6 +79,43 @@ /// /// The the section belongs to. /// The indicator whether the section is relevant. + /// The of the section. + /// The initial probability for the section. + /// The indicator whether the section needs further analysis. + /// The refined probability for the section. + /// Thrown when is null. + /// Thrown when is invalid. + /// Thrown when the section could not be successfully assembled. + public static FailureMechanismSectionAssemblyResult AssembleSection( + IAssessmentSection assessmentSection, + bool isRelevant, NonAdoptableInitialFailureMechanismResultType initialFailureMechanismResultType, + double initialSectionProbability, bool furtherAnalysisNeeded, double refinedSectionProbability) + { + if (assessmentSection == null) + { + throw new ArgumentNullException(nameof(assessmentSection)); + } + + if (!Enum.IsDefined(typeof(NonAdoptableInitialFailureMechanismResultType), initialFailureMechanismResultType)) + { + throw new InvalidEnumArgumentException(nameof(initialFailureMechanismResultType), + (int) initialFailureMechanismResultType, + typeof(NonAdoptableInitialFailureMechanismResultType)); + } + + FailureMechanismSectionAssemblyInput input = CreateInput( + assessmentSection, isRelevant, initialFailureMechanismResultType, + initialSectionProbability, initialSectionProbability, furtherAnalysisNeeded, + refinedSectionProbability, refinedSectionProbability); + + return PerformAssembly(input); + } + + /// + /// Assembles the failure mechanism section based on the input arguments. + /// + /// The the section belongs to. + /// The indicator whether the section is relevant. /// The of the section. /// The initial probability for the profile. /// The initial probability for the section. @@ -169,9 +206,33 @@ bool furtherAnalysisNeeded, double refinedProfileProbability, double refinedSectionProbability) { - FailureMechanismContribution failureMechanismContribution = assessmentSection.FailureMechanismContribution; bool hasProbabilitySpecified = initialFailureMechanismResultType != AdoptableInitialFailureMechanismResultType.NoFailureProbability; + return CreateInput(assessmentSection, isRelevant, hasProbabilitySpecified, + initialProfileProbability, initialSectionProbability, + furtherAnalysisNeeded, refinedProfileProbability, refinedSectionProbability); + } + + private static FailureMechanismSectionAssemblyInput CreateInput(IAssessmentSection assessmentSection, + bool isRelevant, NonAdoptableInitialFailureMechanismResultType initialFailureMechanismResultType, + double initialProfileProbability, double initialSectionProbability, + bool furtherAnalysisNeeded, + double refinedProfileProbability, double refinedSectionProbability) + { + bool hasProbabilitySpecified = initialFailureMechanismResultType != NonAdoptableInitialFailureMechanismResultType.NoFailureProbability; + + return CreateInput(assessmentSection, isRelevant, hasProbabilitySpecified, + initialProfileProbability, initialSectionProbability, + furtherAnalysisNeeded, refinedProfileProbability, refinedSectionProbability); + } + + private static FailureMechanismSectionAssemblyInput CreateInput(IAssessmentSection assessmentSection, + bool isRelevant, bool hasProbabilitySpecified, + double initialProfileProbability, double initialSectionProbability, + bool furtherAnalysisNeeded, + double refinedProfileProbability, double refinedSectionProbability) + { + FailureMechanismContribution failureMechanismContribution = assessmentSection.FailureMechanismContribution; return new FailureMechanismSectionAssemblyInput( failureMechanismContribution.LowerLimitNorm, failureMechanismContribution.SignalingNorm, isRelevant, hasProbabilitySpecified, initialProfileProbability, initialSectionProbability, Index: Riskeer/Common/test/Riskeer.Common.Data.Test/AssemblyTool/FailureMechanismSectionAssemblyGroupFactoryTest.cs =================================================================== diff -u -rc292d279a83c6a04d7020f53fff8a2ad99c68b48 -rb4f2bb1d7e6a8e2028af63b32a6f2ea3d9b6e24e --- Riskeer/Common/test/Riskeer.Common.Data.Test/AssemblyTool/FailureMechanismSectionAssemblyGroupFactoryTest.cs (.../FailureMechanismSectionAssemblyGroupFactoryTest.cs) (revision c292d279a83c6a04d7020f53fff8a2ad99c68b48) +++ Riskeer/Common/test/Riskeer.Common.Data.Test/AssemblyTool/FailureMechanismSectionAssemblyGroupFactoryTest.cs (.../FailureMechanismSectionAssemblyGroupFactoryTest.cs) (revision b4f2bb1d7e6a8e2028af63b32a6f2ea3d9b6e24e) @@ -39,16 +39,144 @@ [TestFixture] public class FailureMechanismSectionAssemblyGroupFactoryTest { - #region Assemble section without profile probability + #region Assemble section with non-adoptable initial failure mechanism result type and without profile probability [Test] - public void AssembleSectionWithoutProfileProbability_AssessmentSectionNull_ThrowsArgumentNullException() + public void AssembleSectionNonAdoptableWithoutProfileProbability_AssessmentSectionNull_ThrowsArgumentNullException() { // Setup var random = new Random(21); // Call void Call() => FailureMechanismSectionAssemblyGroupFactory.AssembleSection( + null, random.NextBoolean(), random.NextEnumValue(), + random.NextDouble(), random.NextBoolean(), random.NextDouble()); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("assessmentSection", exception.ParamName); + } + + [Test] + public void AssembleSectionNonAdoptableWithoutProfileProbability_InvalidInitialFailureMechanismResultType_ThrowsInvalidEnumArgumentException() + { + // Setup + var random = new Random(21); + + const AdoptableInitialFailureMechanismResultType initialFailureMechanismResultType = (AdoptableInitialFailureMechanismResultType) 99; + + // Call + void Call() => FailureMechanismSectionAssemblyGroupFactory.AssembleSection( + new AssessmentSectionStub(), random.NextBoolean(), initialFailureMechanismResultType, + random.NextDouble(), random.NextBoolean(), random.NextDouble()); + + // Assert + var expectedMessage = $"The value of argument 'initialFailureMechanismResultType' ({initialFailureMechanismResultType}) is invalid for Enum type '{nameof(AdoptableInitialFailureMechanismResultType)}'."; + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(Call, expectedMessage); + } + + [Test] + [TestCase(NonAdoptableInitialFailureMechanismResultType.Manual, true)] + [TestCase(NonAdoptableInitialFailureMechanismResultType.NoFailureProbability, false)] + public void AssembleSectionNonAdoptableWithoutProfileProbability_WithInput_SetsInputOnCalculator(NonAdoptableInitialFailureMechanismResultType initialFailureMechanismResultType, + bool expectedHasProbabilitySpecified) + { + // Setup + var random = new Random(21); + bool isRelevant = random.NextBoolean(); + double sectionProbability = random.NextDouble(); + bool furtherAnalysisNeeded = random.NextBoolean(); + double refinedSectionProbability = random.NextDouble(); + + var assessmentSection = new AssessmentSectionStub(); + + using (new AssemblyToolCalculatorFactoryConfig()) + { + var calculatorFactory = (TestAssemblyToolCalculatorFactory) AssemblyToolCalculatorFactory.Instance; + FailureMechanismSectionAssemblyCalculatorStub calculator = calculatorFactory.LastCreatedFailureMechanismSectionAssemblyCalculator; + + // Call + FailureMechanismSectionAssemblyGroupFactory.AssembleSection( + assessmentSection, isRelevant, initialFailureMechanismResultType, + sectionProbability, furtherAnalysisNeeded, refinedSectionProbability); + + // Assert + FailureMechanismSectionAssemblyInput calculatorInput = calculator.FailureMechanismSectionAssemblyInput; + FailureMechanismContribution failureMechanismContribution = assessmentSection.FailureMechanismContribution; + Assert.AreEqual(failureMechanismContribution.SignalingNorm, calculatorInput.SignalingNorm); + Assert.AreEqual(failureMechanismContribution.LowerLimitNorm, calculatorInput.LowerLimitNorm); + + Assert.AreEqual(isRelevant, calculatorInput.IsRelevant); + Assert.AreEqual(expectedHasProbabilitySpecified, calculatorInput.HasProbabilitySpecified); + Assert.AreEqual(sectionProbability, calculatorInput.InitialProfileProbability); + Assert.AreEqual(sectionProbability, calculatorInput.InitialSectionProbability); + Assert.AreEqual(furtherAnalysisNeeded, calculatorInput.FurtherAnalysisNeeded); + Assert.AreEqual(refinedSectionProbability, calculatorInput.RefinedProfileProbability); + Assert.AreEqual(refinedSectionProbability, calculatorInput.RefinedSectionProbability); + } + } + + [Test] + public void AssembleSectionNonAdoptableWithoutProfileProbability_CalculatorRan_ReturnsOutput() + { + // Setup + var random = new Random(21); + using (new AssemblyToolCalculatorFactoryConfig()) + { + var calculatorFactory = (TestAssemblyToolCalculatorFactory) AssemblyToolCalculatorFactory.Instance; + FailureMechanismSectionAssemblyCalculatorStub calculator = calculatorFactory.LastCreatedFailureMechanismSectionAssemblyCalculator; + + // Call + FailureMechanismSectionAssemblyResult output = + FailureMechanismSectionAssemblyGroupFactory.AssembleSection( + new AssessmentSectionStub(), random.NextBoolean(), random.NextEnumValue(), + random.NextDouble(), random.NextBoolean(), random.NextDouble()); + + // Assert + FailureMechanismSectionAssemblyResult calculatorOutput = calculator.FailureMechanismSectionAssemblyResultOutput; + Assert.AreEqual(calculatorOutput.N, output.N); + Assert.AreEqual(calculatorOutput.AssemblyGroup, output.AssemblyGroup); + Assert.AreEqual(calculatorOutput.ProfileProbability, output.ProfileProbability); + Assert.AreEqual(calculatorOutput.SectionProbability, output.SectionProbability); + } + } + + [Test] + public void AssembleSectionNonAdoptableWithoutProfileProbability_CalculatorThrowsException_ThrowsAssemblyException() + { + // Setup + var random = new Random(21); + using (new AssemblyToolCalculatorFactoryConfig()) + { + var calculatorFactory = (TestAssemblyToolCalculatorFactory) AssemblyToolCalculatorFactory.Instance; + FailureMechanismSectionAssemblyCalculatorStub calculator = calculatorFactory.LastCreatedFailureMechanismSectionAssemblyCalculator; + calculator.ThrowExceptionOnCalculate = true; + + // Call + void Call() => FailureMechanismSectionAssemblyGroupFactory.AssembleSection( + new AssessmentSectionStub(), random.NextBoolean(), random.NextEnumValue(), + random.NextDouble(), random.NextBoolean(), random.NextDouble()); + + // Assert + var exception = Assert.Throws(Call); + Exception innerException = exception.InnerException; + Assert.IsInstanceOf(innerException); + Assert.AreEqual(innerException.Message, exception.Message); + } + } + + #endregion + + #region Assemble section with adoptable initial failure mechanism result type and without profile probability + + [Test] + public void AssembleSectionAdoptableWithoutProfileProbability_AssessmentSectionNull_ThrowsArgumentNullException() + { + // Setup + var random = new Random(21); + + // Call + void Call() => FailureMechanismSectionAssemblyGroupFactory.AssembleSection( null, random.NextBoolean(), random.NextEnumValue(), random.NextDouble(), random.NextBoolean(), random.NextDouble()); @@ -58,7 +186,7 @@ } [Test] - public void AssembleSectionWithoutProfileProbability_InvalidInitialFailureMechanismResultType_ThrowsInvalidEnumArgumentException() + public void AssembleSectionAdoptableWithoutProfileProbability_InvalidInitialFailureMechanismResultType_ThrowsInvalidEnumArgumentException() { // Setup var random = new Random(21); @@ -79,8 +207,8 @@ [TestCase(AdoptableInitialFailureMechanismResultType.Adopt, true)] [TestCase(AdoptableInitialFailureMechanismResultType.Manual, true)] [TestCase(AdoptableInitialFailureMechanismResultType.NoFailureProbability, false)] - public void AssembleSectionWithoutProfileProbability_WithInput_SetsInputOnCalculator(AdoptableInitialFailureMechanismResultType initialFailureMechanismResultType, - bool expectedHasProbabilitySpecified) + public void AssembleSectionAdoptableWithoutProfileProbability_WithInput_SetsInputOnCalculator(AdoptableInitialFailureMechanismResultType initialFailureMechanismResultType, + bool expectedHasProbabilitySpecified) { // Setup var random = new Random(21); @@ -118,7 +246,7 @@ } [Test] - public void AssembleSectionWithoutProfileProbability_CalculatorRan_ReturnsOutput() + public void AssembleSectionAdoptableWithoutProfileProbability_CalculatorRan_ReturnsOutput() { // Setup var random = new Random(21); @@ -143,7 +271,7 @@ } [Test] - public void AssembleSectionWithoutProfileProbability_CalculatorThrowsException_ThrowsAssemblyException() + public void AssembleSectionAdoptableWithoutProfileProbability_CalculatorThrowsException_ThrowsAssemblyException() { // Setup var random = new Random(21); @@ -168,7 +296,7 @@ #endregion - #region Assemble section with profile probability + #region Assemble section with adoptable initial failure mechanism result type and with profile probability [Test] public void AssembleSectionWithProfileProbability_AssessmentSectionNull_ThrowsArgumentNullException()