public void ScenariosView_ChangeStructureOfCalculation_ChangesCorrectlyObservedAndSynced()
        {
            // Setup
            var mocks           = new MockRepository();
            var messageProvider = mocks.Stub <IImporterMessageProvider>();

            mocks.ReplayAll();

            using (var form = new Form())
            {
                var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);
                DataImportHelper.ImportReferenceLine(assessmentSection);
                ClosingStructuresFailureMechanism failureMechanism = assessmentSection.ClosingStructures;
                DataImportHelper.ImportFailureMechanismSections(assessmentSection, failureMechanism);

                var view = new ClosingStructuresScenariosView(assessmentSection.ClosingStructures.CalculationsGroup, assessmentSection.ClosingStructures);
                form.Controls.Add(view);
                form.Show();

                var structuresImporter = new ClosingStructuresImporter(assessmentSection.ClosingStructures.ClosingStructures,
                                                                       assessmentSection.ReferenceLine, filePath, messageProvider,
                                                                       new ClosingStructureReplaceDataStrategy(failureMechanism));
                structuresImporter.Import();

                foreach (ClosingStructure structure in assessmentSection.ClosingStructures.ClosingStructures)
                {
                    assessmentSection.ClosingStructures.CalculationsGroup.Children.Add(new StructuresCalculationScenario <ClosingStructuresInput>
                    {
                        Name            = NamingHelper.GetUniqueName(assessmentSection.ClosingStructures.CalculationsGroup.Children, structure.Name + " Calculation", c => c.Name),
                        InputParameters =
                        {
                            Structure = structure
                        }
                    });
                }

                var listBox      = (ListBox) new ControlTester("listBox").TheObject;
                var dataGridView = (DataGridView) new ControlTester("dataGridView").TheObject;

                listBox.SelectedItem = failureMechanism.Sections.ElementAt(32);

                // Precondition
                DataGridViewRowCollection rows = dataGridView.Rows;
                Assert.AreEqual(1, rows.Count);
                Assert.AreEqual("Eerste kunstwerk sluiting 6-3 Calculation", rows[0].Cells[nameColumnIndex].FormattedValue);

                // Call
                CalculationGroup calculationsGroup = assessmentSection.ClosingStructures.CalculationsGroup;
                ((StructuresCalculation <ClosingStructuresInput>)calculationsGroup.Children[1]).InputParameters.Structure =
                    ((StructuresCalculation <ClosingStructuresInput>)calculationsGroup.Children[0]).InputParameters.Structure;
                calculationsGroup.NotifyObservers();

                // Assert
                Assert.AreEqual(2, rows.Count);
                Assert.AreEqual("Eerste kunstwerk sluiting 6-3 Calculation", rows[0].Cells[nameColumnIndex].FormattedValue);
                Assert.AreEqual("Tweede kunstwerk sluiting 6-3 Calculation", rows[1].Cells[nameColumnIndex].FormattedValue);
            }

            mocks.VerifyAll();
        }
コード例 #2
0
        public void Import_ValidFileWithScenarioInformation_UpdatesHydraulicBoundaryDatabaseWithImportedData()
        {
            // Setup
            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validHrdFilePath);
            HydraulicBoundaryDatabase hydraulicBoundaryDatabase = assessmentSection.HydraulicBoundaryDatabase;

            string filePath = Path.Combine(testDataPath, "hlcdWithValidScenarioInformation.sqlite");

            var mocks   = new MockRepository();
            var handler = mocks.StrictMock <IHydraulicLocationConfigurationDatabaseUpdateHandler>();

            handler.Expect(h => h.InquireConfirmation()).Return(true);
            handler.Expect(h => h.Update(Arg <HydraulicBoundaryDatabase> .Is.Same(hydraulicBoundaryDatabase),
                                         Arg <ReadHydraulicLocationConfigurationDatabaseSettings> .Is.NotNull,
                                         Arg <bool> .Is.Equal(false),
                                         Arg <string> .Is.Equal(filePath)))
            .Return(Enumerable.Empty <IObservable>());
            mocks.ReplayAll();

            var importer = new HydraulicLocationConfigurationDatabaseImporter(hydraulicBoundaryDatabase.HydraulicLocationConfigurationSettings, handler,
                                                                              hydraulicBoundaryDatabase, filePath);

            // Call
            var    importResult = false;
            Action call         = () => importResult = importer.Import();

            // Assert
            TestHelper.AssertLogMessageIsGenerated(call, $"Gegevens zijn geïmporteerd vanuit bestand '{filePath}'.", 1);
            Assert.IsTrue(importResult);
            mocks.VerifyAll();
        }
        public void ScenariosView_ImportFailureMechanismSections_ChangesCorrectlyObservedAndSynced()
        {
            // Setup
            using (var form = new Form())
            {
                var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);
                DataImportHelper.ImportReferenceLine(assessmentSection);

                var view = new ClosingStructuresScenariosView(assessmentSection.ClosingStructures.CalculationsGroup, assessmentSection.ClosingStructures);
                form.Controls.Add(view);
                form.Show();

                var listBox = (ListBox) new ControlTester("listBox").TheObject;

                // Precondition
                CollectionAssert.IsEmpty(listBox.Items);

                // Call
                ClosingStructuresFailureMechanism failureMechanism = assessmentSection.ClosingStructures;
                DataImportHelper.ImportFailureMechanismSections(assessmentSection, failureMechanism);
                assessmentSection.ClosingStructures.NotifyObservers();

                // Assert
                CollectionAssert.AreEqual(assessmentSection.ClosingStructures.Sections, listBox.Items);
            }
        }
コード例 #4
0
        public void Import_LocationIdNotInHlcd_CancelImportWithErrorMessage()
        {
            // Setup
            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validHrdFilePath);
            HydraulicBoundaryDatabase hydraulicBoundaryDatabase = assessmentSection.HydraulicBoundaryDatabase;

            hydraulicBoundaryDatabase.Locations.Add(new TestHydraulicBoundaryLocation());

            var mocks   = new MockRepository();
            var handler = mocks.StrictMock <IHydraulicLocationConfigurationDatabaseUpdateHandler>();

            handler.Stub(h => h.InquireConfirmation()).Return(true);
            mocks.ReplayAll();

            var importer = new HydraulicLocationConfigurationDatabaseImporter(hydraulicBoundaryDatabase.HydraulicLocationConfigurationSettings, handler,
                                                                              hydraulicBoundaryDatabase, validHlcdFilePath);

            // Call
            var    importSuccessful = true;
            Action call             = () => importSuccessful = importer.Import();

            // Assert
            string expectedMessage = $"Fout bij het lezen van bestand '{validHlcdFilePath}': 1 of meerdere locaties komen niet voor in de HLCD.";

            AssertImportFailed(call, expectedMessage, ref importSuccessful);
            mocks.VerifyAll();
        }
        public void Run_ValidCalculation_InputPropertiesCorrectlySentToService()
        {
            // Setup
            var mocks = new MockRepository();
            var profileSpecificCalculator = new TestPipingCalculator();
            var sectionSpecificCalculator = new TestPipingCalculator();
            var calculatorFactory         = mocks.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(profileSpecificCalculator)
            .Repeat.Once();
            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(sectionSpecificCalculator)
            .Repeat.Once();
            mocks.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            TestPipingFailureMechanism failureMechanism = TestPipingFailureMechanism.GetFailureMechanismWithSurfaceLinesAndStochasticSoilModels();
            var calculation = ProbabilisticPipingCalculationTestFactory.CreateCalculationWithValidInput <TestProbabilisticPipingCalculation>(
                assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001));

            calculation.InputParameters.HydraulicBoundaryLocation = assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001);

            CalculatableActivity activity = PipingCalculationActivityFactory.CreateProbabilisticPipingCalculationActivity(
                calculation, failureMechanism, assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                activity.Run();

                // Assert
                PipingCalculationInput[] profileSpecificInputs = profileSpecificCalculator.ReceivedInputs.ToArray();
                PipingCalculationInput[] sectionSpecificInputs = sectionSpecificCalculator.ReceivedInputs.ToArray();

                Assert.AreEqual(1, profileSpecificInputs.Length);
                Assert.AreEqual(1, sectionSpecificInputs.Length);

                double sectionLength = failureMechanism.Sections.Single(
                    s => calculation.IsSurfaceLineIntersectionWithReferenceLineInSection(
                        Math2D.ConvertPointsToLineSegments(s.Points))).Length;

                AssertCalculatorInput(failureMechanism.GeneralInput, calculation.InputParameters, 0, profileSpecificInputs[0]);
                AssertCalculatorInput(failureMechanism.GeneralInput, calculation.InputParameters, sectionLength, sectionSpecificInputs[0]);
            }

            mocks.VerifyAll();
        }
コード例 #6
0
        public void Finish_InvalidCalculationAndRan_DoesNotSetOutputAndNotifyObserversOfCalculation(bool endInFailure,
                                                                                                    string lastErrorFileContent)
        {
            // Setup
            var mockRepository = new MockRepository();
            var observer       = mockRepository.StrictMock <IObserver>();

            observer.Expect(o => o.UpdateObserver());

            var calculator = new TestStructuresCalculator <StructuresClosureCalculationInput>
            {
                EndInFailure         = endInFailure,
                LastErrorFileContent = lastErrorFileContent
            };
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateStructuresCalculator <StructuresClosureCalculationInput>(null))
            .IgnoreArguments()
            .Return(calculator);
            mockRepository.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            var failureMechanism = new ClosingStructuresFailureMechanism();
            var calculation      = new StructuresCalculation <ClosingStructuresInput>
            {
                InputParameters =
                {
                    HydraulicBoundaryLocation = new HydraulicBoundaryLocation(1, "test", 1, 1),
                    Structure                 = new TestClosingStructure()
                }
            };

            calculation.Attach(observer);

            CalculatableActivity activity = ClosingStructuresCalculationActivityFactory.CreateCalculationActivity(calculation,
                                                                                                                  failureMechanism,
                                                                                                                  assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                activity.Run();
            }

            // Call
            activity.Finish();

            // Assert
            Assert.IsNull(calculation.Output);
            mockRepository.VerifyAll();
        }
コード例 #7
0
        public void Run_ValidCalculation_PerformValidationAndCalculationAndLogStartAndEnd()
        {
            // Setup
            var mockRepository    = new MockRepository();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateStructuresCalculator <StructuresStabilityPointCalculationInput>(null))
            .IgnoreArguments()
            .Return(new TestStructuresCalculator <StructuresStabilityPointCalculationInput>());
            mockRepository.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            var failureMechanism = new StabilityPointStructuresFailureMechanism();
            var calculation      = new TestStabilityPointStructuresCalculationScenario
            {
                InputParameters =
                {
                    HydraulicBoundaryLocation = assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001),
                    InflowModelType           = StabilityPointStructureInflowModelType.LowSill,
                    LoadSchematizationType    = LoadSchematizationType.Linear
                }
            };

            CalculatableActivity activity = StabilityPointStructuresCalculationActivityFactory.CreateCalculationActivity(calculation,
                                                                                                                         failureMechanism,
                                                                                                                         assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                Action call = () => activity.Run();

                // Assert
                TestHelper.AssertLogMessages(call, messages =>
                {
                    string[] msgs = messages.ToArray();
                    Assert.AreEqual(6, msgs.Length);
                    Assert.AreEqual($"Uitvoeren van berekening '{calculation.Name}' is gestart.", msgs[0]);
                    CalculationServiceTestHelper.AssertValidationStartMessage(msgs[1]);
                    CalculationServiceTestHelper.AssertValidationEndMessage(msgs[2]);
                    CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[3]);
                    StringAssert.StartsWith("Puntconstructies berekening is uitgevoerd op de tijdelijke locatie", msgs[4]);
                    CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[5]);
                });
                Assert.AreEqual(ActivityState.Executed, activity.State);
            }

            mockRepository.VerifyAll();
        }
コード例 #8
0
        public void Finish_ValidCalculationAndRan_SetsOutputAndNotifyObserversOfCalculation()
        {
            // Setup
            var mockRepository = new MockRepository();
            var observer       = mockRepository.StrictMock <IObserver>();

            observer.Expect(o => o.UpdateObserver());

            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateStructuresCalculator <StructuresStabilityPointCalculationInput>(null))
            .IgnoreArguments()
            .Return(new TestStructuresCalculator <StructuresStabilityPointCalculationInput>());
            mockRepository.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            var failureMechanism = new StabilityPointStructuresFailureMechanism();
            var calculation      = new TestStabilityPointStructuresCalculationScenario
            {
                InputParameters =
                {
                    HydraulicBoundaryLocation = assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001),
                    InflowModelType           = StabilityPointStructureInflowModelType.LowSill,
                    LoadSchematizationType    = LoadSchematizationType.Linear
                }
            };

            calculation.Attach(observer);

            CalculatableActivity activity = StabilityPointStructuresCalculationActivityFactory.CreateCalculationActivity(calculation,
                                                                                                                         failureMechanism,
                                                                                                                         assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                activity.Run();
            }

            // Call
            activity.Finish();

            // Assert
            Assert.IsNotNull(calculation.Output);
            mockRepository.VerifyAll();
        }
コード例 #9
0
        public void Run_InvalidCalculationRan_PerformValidationAndCalculationActivityStateFailed(bool endInFailure, string lastErrorFileContent)
        {
            // Setup
            var calculator = new TestStructuresCalculator <StructuresStabilityPointCalculationInput>
            {
                EndInFailure         = endInFailure,
                LastErrorFileContent = lastErrorFileContent
            };

            var mockRepository    = new MockRepository();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateStructuresCalculator <StructuresStabilityPointCalculationInput>(null))
            .IgnoreArguments()
            .Return(calculator);
            mockRepository.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            var failureMechanism = new StabilityPointStructuresFailureMechanism();
            var calculation      = new TestStabilityPointStructuresCalculationScenario
            {
                InputParameters =
                {
                    HydraulicBoundaryLocation = new HydraulicBoundaryLocation(1,                "test", 1, 1),
                    InflowModelType           = StabilityPointStructureInflowModelType.LowSill,
                    LoadSchematizationType    = LoadSchematizationType.Linear
                }
            };

            CalculatableActivity activity = StabilityPointStructuresCalculationActivityFactory.CreateCalculationActivity(calculation,
                                                                                                                         failureMechanism,
                                                                                                                         assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                activity.Run();

                // Assert
                Assert.AreEqual(ActivityState.Failed, activity.State);
            }

            mockRepository.VerifyAll();
        }
        public void Run_ValidCalculation_PerformValidationAndCalculationAndLogStartAndEnd()
        {
            // Setup
            var mocks             = new MockRepository();
            var calculatorFactory = mocks.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(new TestPipingCalculator())
            .Repeat.Twice();
            mocks.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            TestPipingFailureMechanism failureMechanism = TestPipingFailureMechanism.GetFailureMechanismWithSurfaceLinesAndStochasticSoilModels();
            var calculation = ProbabilisticPipingCalculationTestFactory.CreateCalculationWithValidInput <TestProbabilisticPipingCalculation>(
                assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001));

            CalculatableActivity activity = PipingCalculationActivityFactory.CreateProbabilisticPipingCalculationActivity(
                calculation, failureMechanism, assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                void Call() => activity.Run();

                // Assert
                TestHelper.AssertLogMessages(Call, messages =>
                {
                    string[] msgs = messages.ToArray();
                    Assert.AreEqual(7, msgs.Length);
                    Assert.AreEqual($"Uitvoeren van berekening '{calculation.Name}' is gestart.", msgs[0]);
                    CalculationServiceTestHelper.AssertValidationStartMessage(msgs[1]);
                    CalculationServiceTestHelper.AssertValidationEndMessage(msgs[2]);
                    CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[3]);
                    StringAssert.StartsWith("De piping sterkte berekening voor doorsnede is uitgevoerd op de tijdelijke locatie", msgs[4]);
                    StringAssert.StartsWith("De piping sterkte berekening voor vak is uitgevoerd op de tijdelijke locatie", msgs[5]);
                    CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[6]);
                });
                Assert.AreEqual(ActivityState.Executed, activity.State);
            }

            mocks.VerifyAll();
        }
        public void Run_ValidCalculation_ProgressTextSetAccordingly()
        {
            // Setup
            var mocks             = new MockRepository();
            var calculatorFactory = mocks.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(new TestPipingCalculator())
            .Repeat.Twice();
            mocks.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            TestPipingFailureMechanism failureMechanism = TestPipingFailureMechanism.GetFailureMechanismWithSurfaceLinesAndStochasticSoilModels();
            var calculation = ProbabilisticPipingCalculationTestFactory.CreateCalculationWithValidInput <TestProbabilisticPipingCalculation>(
                assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001));

            CalculatableActivity activity = PipingCalculationActivityFactory.CreateProbabilisticPipingCalculationActivity(
                calculation, failureMechanism, assessmentSection);

            var progressTexts = "";

            activity.ProgressChanged += (s, e) => progressTexts += activity.ProgressText + Environment.NewLine;

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                activity.Run();

                // Assert
                string expectedProgressTexts = "Stap 1 van 2 | Uitvoeren sterkte berekening voor doorsnede" + Environment.NewLine +
                                               "Stap 2 van 2 | Uitvoeren sterkte berekening voor vak" + Environment.NewLine;

                Assert.AreEqual(expectedProgressTexts, progressTexts);
            }

            mocks.VerifyAll();
        }
        public void GivenProbabilisticPipingCalculationActivity_WhenRunAndFinished_ThenOutputSetAndObserversNotified()
        {
            // Given
            var mocks    = new MockRepository();
            var observer = mocks.StrictMock <IObserver>();

            observer.Expect(o => o.UpdateObserver());
            var calculatorFactory = mocks.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(new TestPipingCalculator())
            .Repeat.Twice();
            mocks.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            TestPipingFailureMechanism failureMechanism = TestPipingFailureMechanism.GetFailureMechanismWithSurfaceLinesAndStochasticSoilModels();
            var calculation = ProbabilisticPipingCalculationTestFactory.CreateCalculationWithValidInput <TestProbabilisticPipingCalculation>(
                assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001));

            calculation.Attach(observer);

            CalculatableActivity activity = PipingCalculationActivityFactory.CreateProbabilisticPipingCalculationActivity(
                calculation, failureMechanism, assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // When
                activity.Run();
                activity.Finish();

                // Then
                Assert.IsNotNull(calculation.Output);
            }

            mocks.VerifyAll();
        }
        public void ImportHydraulicLocationConfigurationSettings_WithValidFilePath_RunsActivity()
        {
            // Setup
            string newHlcdFilePath = Path.Combine(testDataDirectory, "hlcdWithScenarioInformation.sqlite");

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection,
                                                             Path.Combine(testDataDirectory, "complete.sqlite"));

            HydraulicBoundaryDatabase hydraulicBoundaryDatabase = assessmentSection.HydraulicBoundaryDatabase;

            var mocks         = new MockRepository();
            var updateHandler = mocks.Stub <IHydraulicLocationConfigurationDatabaseUpdateHandler>();

            mocks.ReplayAll();

            DialogBoxHandler = (name, wnd) =>
            {
                // Activity closes itself
            };

            using (var viewParent = new TestViewParentForm())
            {
                var importHandler = new HydraulicLocationConfigurationDatabaseImportHandler(
                    viewParent, updateHandler, hydraulicBoundaryDatabase);

                // Call
                importHandler.ImportHydraulicLocationConfigurationSettings(
                    hydraulicBoundaryDatabase.HydraulicLocationConfigurationSettings,
                    newHlcdFilePath);
            }

            // Assert
            mocks.VerifyAll();
        }
コード例 #14
0
        public void ScenariosView_GenerateCalculations_ChangesCorrectlyObservedAndSynced()
        {
            // Setup
            var mocks           = new MockRepository();
            var messageProvider = mocks.Stub <IImporterMessageProvider>();

            mocks.ReplayAll();

            using (var form = new Form())
            {
                var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);
                DataImportHelper.ImportReferenceLine(assessmentSection);
                ClosingStructuresFailureMechanism failureMechanism = assessmentSection.ClosingStructures;
                DataImportHelper.ImportFailureMechanismSections(assessmentSection, failureMechanism);

                CalculationGroup calculationsGroup = assessmentSection.ClosingStructures.CalculationsGroup;
                var view = new ClosingStructuresScenariosView(calculationsGroup, assessmentSection.ClosingStructures);

                form.Controls.Add(view);
                form.Show();

                var structuresImporter = new ClosingStructuresImporter(assessmentSection.ClosingStructures.ClosingStructures,
                                                                       assessmentSection.ReferenceLine, filePath, messageProvider,
                                                                       new ClosingStructureReplaceDataStrategy(failureMechanism));
                structuresImporter.Import();

                var listBox      = (ListBox) new ControlTester("listBox").TheObject;
                var dataGridView = (DataGridView) new ControlTester("dataGridView").TheObject;

                listBox.SelectedItem = failureMechanism.Sections.ElementAt(32);

                // Precondition
                DataGridViewRowCollection rows = dataGridView.Rows;
                CollectionAssert.IsEmpty(rows);

                // Call
                foreach (ClosingStructure structure in assessmentSection.ClosingStructures.ClosingStructures)
                {
                    calculationsGroup.Children.Add(new StructuresCalculationScenario <ClosingStructuresInput>
                    {
                        Name            = NamingHelper.GetUniqueName(((CalculationGroup)view.Data).Children, structure.Name, c => c.Name),
                        InputParameters =
                        {
                            Structure = structure
                        }
                    });
                }

                calculationsGroup.NotifyObservers();

                // Assert
                Assert.AreEqual(1, rows.Count);

                DataGridViewCellCollection cells = rows[0].Cells;
                Assert.AreEqual(4, cells.Count);
                Assert.IsTrue(Convert.ToBoolean(cells[isRelevantColumnIndex].FormattedValue));
                Assert.AreEqual(new RoundedDouble(2, 100).ToString(), cells[contributionColumnIndex].FormattedValue);
                Assert.AreEqual("Eerste kunstwerk sluiting 6-3", cells[nameColumnIndex].FormattedValue);
                Assert.AreEqual("-", cells[failureProbabilityColumnIndex].FormattedValue);
            }

            mocks.VerifyAll();
        }
コード例 #15
0
        public void GivenAssessmentSectionWithReferenceLineAndOtherData_WhenImportingReferenceLine_ThenReferenceLineGeometryReplacedAndReferenceLineDependentDataCleared()
        {
            // Given
            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            var mocks                    = new MockRepository();
            var viewCommands             = mocks.Stub <IViewCommands>();
            var failureMechanismObserver = mocks.StrictMock <IObserver>();

            failureMechanismObserver.Expect(o => o.UpdateObserver())
            .Repeat.Times(assessmentSection.GetFailureMechanisms().Count());
            var referenceLineObserver = mocks.StrictMock <IObserver>();

            referenceLineObserver.Expect(o => o.UpdateObserver());
            var surfaceLinesObserver = mocks.StrictMock <IObserver>();

            surfaceLinesObserver.Expect(o => o.UpdateObserver());
            var stochasticSoilModelsObserver = mocks.StrictMock <IObserver>();

            stochasticSoilModelsObserver.Expect(o => o.UpdateObserver());
            mocks.ReplayAll();

            DataImportHelper.ImportReferenceLine(assessmentSection);
            DataImportHelper.ImportFailureMechanismSections(assessmentSection, assessmentSection.GetFailureMechanisms()
                                                            .Cast <IFailureMechanism <FailureMechanismSectionResult> >());
            DataImportHelper.ImportPipingSurfaceLines(assessmentSection);
            DataImportHelper.ImportPipingStochasticSoilModels(assessmentSection);

            ReferenceLine originalReferenceLine = assessmentSection.ReferenceLine;

            Point2D[] originalReferenceLineGeometry = originalReferenceLine.Points.ToArray();

            var    handler = new ReferenceLineUpdateHandler(assessmentSection, viewCommands);
            string path    = TestHelper.GetTestDataPath(TestDataPath.Riskeer.Common.IO,
                                                        Path.Combine("ReferenceLine", "traject_10-2.shp"));

            var importer = new ReferenceLineImporter(assessmentSection.ReferenceLine, handler, path);

            string messageBoxTitle = null, messageBoxText = null;

            DialogBoxHandler = (name, wnd) =>
            {
                var messageBoxTester = new MessageBoxTester(wnd);

                messageBoxTitle = messageBoxTester.Title;
                messageBoxText  = messageBoxTester.Text;

                messageBoxTester.ClickOk();
            };

            assessmentSection.ReferenceLine.Attach(referenceLineObserver);
            foreach (IFailureMechanism failureMechanism in assessmentSection.GetFailureMechanisms())
            {
                failureMechanism.Attach(failureMechanismObserver);
            }

            assessmentSection.Piping.StochasticSoilModels.Attach(stochasticSoilModelsObserver);
            assessmentSection.Piping.SurfaceLines.Attach(surfaceLinesObserver);

            // When
            bool importSuccessful = importer.Import();

            importer.DoPostImport();

            // Then
            Assert.IsTrue(importSuccessful);
            Assert.AreSame(originalReferenceLine, assessmentSection.ReferenceLine);
            CollectionAssert.AreNotEqual(originalReferenceLineGeometry, assessmentSection.ReferenceLine.Points);
            Point2D[] point2Ds = assessmentSection.ReferenceLine.Points.ToArray();
            Assert.AreEqual(803, point2Ds.Length);
            Assert.AreEqual(198237.375, point2Ds[123].X, 1e-6);
            Assert.AreEqual(514879.781, point2Ds[123].Y, 1e-6);

            foreach (IFailureMechanism failureMechanism in assessmentSection.GetFailureMechanisms())
            {
                CollectionAssert.IsEmpty(failureMechanism.Sections);
            }

            CollectionAssert.IsEmpty(assessmentSection.Piping.SurfaceLines);
            CollectionAssert.IsEmpty(assessmentSection.Piping.StochasticSoilModels);
            CollectionAssert.IsEmpty(assessmentSection.Piping.CalculationsGroup.Children);

            Assert.AreEqual("Bevestigen", messageBoxTitle);
            string expectedText = "Na het importeren van een aangepaste ligging van de referentielijn zullen alle geïmporteerde en berekende gegevens van alle faalmechanismen worden gewist." + Environment.NewLine +
                                  Environment.NewLine + "Wilt u doorgaan?";

            Assert.AreEqual(expectedText, messageBoxText);

            mocks.VerifyAll();
        }
コード例 #16
0
        public void PipingCalculationsView_DataImportedOrChanged_ChangesCorrectlyObservedAndSynced()
        {
            // Setup
            using (var form = new Form())
            {
                var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);
                PipingFailureMechanism failureMechanism = assessmentSection.Piping;

                // Show the view
                var pipingCalculationsView = new PipingCalculationsView(failureMechanism.CalculationsGroup, failureMechanism, assessmentSection);
                form.Controls.Add(pipingCalculationsView);
                form.Show();

                // Obtain some relevant controls
                var dataGridView = (DataGridView) new ControlTester("dataGridView").TheObject;

                // Import failure mechanism sections
                DataImportHelper.ImportReferenceLine(assessmentSection);
                DataImportHelper.ImportFailureMechanismSections(assessmentSection, failureMechanism);

                // Import surface lines
                DataImportHelper.ImportPipingSurfaceLines(assessmentSection);

                // Setup some calculations
                var calculation1 = new SemiProbabilisticPipingCalculationScenario
                {
                    InputParameters =
                    {
                        SurfaceLine = failureMechanism.SurfaceLines.First(sl => sl.Name == "PK001_0001")
                    }
                };
                var calculation2 = new ProbabilisticPipingCalculationScenario
                {
                    InputParameters =
                    {
                        SurfaceLine = failureMechanism.SurfaceLines.First(sl => sl.Name == "PK001_0001")
                    }
                };

                // Add a piping calculation and ensure it is shown in the data grid view
                failureMechanism.CalculationsGroup.Children.Add(calculation1);
                failureMechanism.CalculationsGroup.NotifyObservers();
                Assert.AreEqual(1, dataGridView.Rows.Count);

                // Import soil models and profiles and ensure the corresponding combobox items are updated
                DataImportHelper.ImportPipingStochasticSoilModels(assessmentSection);
                PipingStochasticSoilModelCollection stochasticSoilModelCollection = failureMechanism.StochasticSoilModels;
                calculation1.InputParameters.StochasticSoilModel = stochasticSoilModelCollection.First(sl => sl.Name == "PK001_0001_Piping");
                Assert.AreEqual(2, ((DataGridViewComboBoxCell)dataGridView.Rows[0].Cells[stochasticSoilModelsColumnIndex]).Items.Count);
                Assert.AreEqual("PK001_0001_Piping", dataGridView.Rows[0].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual(1, ((DataGridViewComboBoxCell)dataGridView.Rows[0].Cells[stochasticSoilProfilesColumnIndex]).Items.Count);
                Assert.AreEqual("<selecteer>", dataGridView.Rows[0].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);

                // Import hydraulic boundary locations and ensure the corresponding combobox items are updated
                DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection);
                assessmentSection.HydraulicBoundaryDatabase.Locations.NotifyObservers();
                Assert.AreEqual(19, ((DataGridViewComboBoxCell)dataGridView.Rows[0].Cells[hydraulicBoundaryLocationsColumnIndex]).Items.Count);

                // Add group and ensure the data grid view is not changed
                var nestedPipingCalculationGroup = new CalculationGroup();
                failureMechanism.CalculationsGroup.Children.Add(nestedPipingCalculationGroup);
                failureMechanism.CalculationsGroup.NotifyObservers();
                Assert.AreEqual(1, dataGridView.Rows.Count);

                // Add another, nested calculation and ensure the data grid view is updated
                nestedPipingCalculationGroup.Children.Add(calculation2);
                nestedPipingCalculationGroup.NotifyObservers();
                Assert.AreEqual(2, dataGridView.Rows.Count);

                // Change the name of the first calculation and ensure the data grid view is updated
                calculation1.Name = "New name";
                calculation1.NotifyObservers();
                Assert.AreEqual("New name", dataGridView.Rows[0].Cells[nameColumnIndex].FormattedValue);

                // Change an input parameter of the second calculation and ensure the data grid view is updated
                var exitPointL = new RoundedDouble(2, 111.11);
                calculation2.InputParameters.ExitPointL = exitPointL;
                calculation2.InputParameters.NotifyObservers();
                Assert.AreEqual(exitPointL.ToString(), dataGridView.Rows[1].Cells[exitPointLColumnIndex].FormattedValue);

                // Add another calculation and assign all soil models
                var pipingCalculation3 = new SemiProbabilisticPipingCalculationScenario();
                failureMechanism.CalculationsGroup.Children.Add(pipingCalculation3);
                failureMechanism.CalculationsGroup.NotifyObservers();
                pipingCalculation3.InputParameters.SurfaceLine = failureMechanism.SurfaceLines.First(sl => sl.Name == "PK001_0001");
                pipingCalculation3.InputParameters.NotifyObservers();
                Assert.AreEqual(3, dataGridView.Rows.Count);

                calculation1.InputParameters.StochasticSoilModel   = stochasticSoilModelCollection[0];
                calculation1.InputParameters.StochasticSoilProfile = stochasticSoilModelCollection[0].StochasticSoilProfiles.First();
                calculation1.InputParameters.NotifyObservers();
                Assert.AreEqual("PK001_0001_Piping", dataGridView.Rows[0].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual("W1-6_0_1D1", dataGridView.Rows[0].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);
                Assert.AreEqual(GetFormattedProbabilityValue(100), dataGridView.Rows[0].Cells[stochasticSoilProfilesProbabilityColumnIndex].FormattedValue);

                calculation2.InputParameters.SurfaceLine           = failureMechanism.SurfaceLines.First(sl => sl.Name == "PK001_0002");
                calculation2.InputParameters.StochasticSoilModel   = stochasticSoilModelCollection[1];
                calculation2.InputParameters.StochasticSoilProfile = stochasticSoilModelCollection[1].StochasticSoilProfiles.First();
                calculation2.InputParameters.NotifyObservers();
                Assert.AreEqual("PK001_0002_Piping", dataGridView.Rows[1].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual("W1-6_4_1D1", dataGridView.Rows[1].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);
                Assert.AreEqual(GetFormattedProbabilityValue(100), dataGridView.Rows[1].Cells[stochasticSoilProfilesProbabilityColumnIndex].FormattedValue);

                pipingCalculation3.InputParameters.SurfaceLine           = failureMechanism.SurfaceLines.First(sl => sl.Name == "PK001_0003");
                pipingCalculation3.InputParameters.StochasticSoilModel   = stochasticSoilModelCollection[2];
                pipingCalculation3.InputParameters.StochasticSoilProfile = stochasticSoilModelCollection[2].StochasticSoilProfiles.First();
                pipingCalculation3.InputParameters.NotifyObservers();
                Assert.AreEqual("PK001_0003_Piping", dataGridView.Rows[2].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual("W1-7_0_1D1", dataGridView.Rows[2].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);
                Assert.AreEqual(GetFormattedProbabilityValue(100), dataGridView.Rows[2].Cells[stochasticSoilProfilesProbabilityColumnIndex].FormattedValue);

                // Update stochastic soil models
                DataUpdateHelper.UpdatePipingStochasticSoilModels(assessmentSection);

                Assert.AreEqual("PK001_0001_Piping", dataGridView.Rows[0].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual("W1-6_0_1D1", dataGridView.Rows[0].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);
                Assert.AreEqual(GetFormattedProbabilityValue(50), dataGridView.Rows[0].Cells[stochasticSoilProfilesProbabilityColumnIndex].FormattedValue);

                Assert.AreEqual("PK001_0002_Piping", dataGridView.Rows[1].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual("<selecteer>", dataGridView.Rows[1].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);
                Assert.AreEqual(GetFormattedProbabilityValue(0), dataGridView.Rows[1].Cells[stochasticSoilProfilesProbabilityColumnIndex].FormattedValue);

                Assert.AreEqual("PK001_0003_Piping", dataGridView.Rows[2].Cells[stochasticSoilModelsColumnIndex].FormattedValue);
                Assert.AreEqual("W1-7_0_1D1", dataGridView.Rows[2].Cells[stochasticSoilProfilesColumnIndex].FormattedValue);
                Assert.AreEqual(GetFormattedProbabilityValue(100), dataGridView.Rows[2].Cells[stochasticSoilProfilesProbabilityColumnIndex].FormattedValue);
            }
        }
コード例 #17
0
ファイル: StuInfoController.cs プロジェクト: jieqimin/UCHome
        private DataTable ReadFile(string filepath, out string errormsg)
        {
            DataTable dt    = DataImportHelper.ImportExcelFile(filepath, Path.GetExtension(filepath), 0);
            bool      error = false;

            errormsg = "";
            //移除空行
            int            coulumnCount   = dt.Columns.Count;
            List <DataRow> removeDataRows = new List <DataRow>();

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                int count = 0;
                for (int j = 0; j < coulumnCount; j++)
                {
                    if (dt.Rows[i].IsNull(j) || dt.Rows[i][j].ToString().Trim() == "")
                    {
                        count = count + 1;
                    }
                }
                if (count == coulumnCount)                //整行为空
                {
                    removeDataRows.Add(dt.Rows[i]);
                }
            }
            foreach (DataRow item in removeDataRows)
            {
                dt.Rows.Remove(item);
            }
            //验证文件列符合导入标准
            string[] strArray = { "学段", "进班年份", "毕业年份", "班级", "学籍号", "地区学号", "姓名", "身份证号" };
            if (dt.Columns.Count == strArray.Length)
            {
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    if (strArray[j] != dt.Rows[0][j].ToString().Trim())
                    {
                        errormsg = "上传文件的列名或列序与模板的列名或列序不匹配";
                        dt       = new DataTable();
                        error    = true;
                        break;
                    }
                }
            }
            else
            {
                dt       = new DataTable();
                errormsg = "上传文件的列数与模板的列数不匹配";
                error    = true;
            }
            if (error == false)
            {
                #region dt detail
                //dt.Columns["登录帐号"].ColumnName = "LoginName";
                //dt.Columns["学校"].ColumnName = "XXID";
                dt.Columns["学段"].ColumnName   = "ClassStage";
                dt.Columns["进班年份"].ColumnName = "ClassCreateYear";
                dt.Columns["毕业年份"].ColumnName = "ClassGraduationYear";
                dt.Columns["班级"].ColumnName   = "ClassName";
                dt.Columns["学籍号"].ColumnName  = "StuCode";
                dt.Columns["地区学号"].ColumnName = "StuNumber";
                dt.Columns["姓名"].ColumnName   = "StuName";
                dt.Columns["身份证号"].ColumnName = "StuIdentity";
                #endregion
            }
            return(dt);
        }
        public void Run_InvalidSectionSpecificCalculation_LogErrorAndActivityStateFailedAndOutputNotSet(bool endInFailure,
                                                                                                        string lastErrorFileContent)
        {
            // Setup
            var sectionSpecificCalculator = new TestPipingCalculator
            {
                LastErrorFileContent = lastErrorFileContent,
                EndInFailure         = true
            };

            var mocks    = new MockRepository();
            var observer = mocks.StrictMock <IObserver>();

            var calculatorFactory = mocks.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(new TestPipingCalculator())
            .Repeat.Once();
            calculatorFactory.Expect(cf => cf.CreatePipingCalculator(null))
            .IgnoreArguments()
            .Return(sectionSpecificCalculator)
            .Repeat.Once();
            mocks.ReplayAll();

            var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);

            DataImportHelper.ImportHydraulicBoundaryDatabase(assessmentSection, validFilePath);

            TestPipingFailureMechanism failureMechanism = TestPipingFailureMechanism.GetFailureMechanismWithSurfaceLinesAndStochasticSoilModels();
            var calculation = ProbabilisticPipingCalculationTestFactory.CreateCalculationWithValidInput <TestProbabilisticPipingCalculation>(
                assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001));

            calculation.Attach(observer);

            CalculatableActivity activity = PipingCalculationActivityFactory.CreateProbabilisticPipingCalculationActivity(
                calculation, failureMechanism, assessmentSection);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                void Call() => activity.Run();

                // Assert
                TestHelper.AssertLogMessages(Call, messages =>
                {
                    string[] msgs = messages.ToArray();
                    Assert.AreEqual(8, msgs.Length);
                    Assert.AreEqual($"Uitvoeren van berekening '{calculation.Name}' is gestart.", msgs[0]);
                    CalculationServiceTestHelper.AssertValidationStartMessage(msgs[1]);
                    CalculationServiceTestHelper.AssertValidationEndMessage(msgs[2]);
                    CalculationServiceTestHelper.AssertCalculationStartMessage(msgs[3]);
                    StringAssert.StartsWith("De piping sterkte berekening voor doorsnede is uitgevoerd op de tijdelijke locatie", msgs[4]);
                    string errorReportText = lastErrorFileContent != null
                                                 ? $"Bekijk het foutrapport door op details te klikken.{Environment.NewLine}{lastErrorFileContent}"
                                                 : "Er is geen foutrapport beschikbaar.";
                    Assert.AreEqual($"De piping sterkte berekening voor vak '{calculation.Name}' is mislukt. {errorReportText}", msgs[5]);
                    StringAssert.StartsWith("De piping sterkte berekening voor vak is uitgevoerd op de tijdelijke locatie", msgs[6]);
                    CalculationServiceTestHelper.AssertCalculationEndMessage(msgs[7]);
                });
                Assert.AreEqual(ActivityState.Failed, activity.State);
                Assert.IsNull(calculation.Output);
            }

            mocks.VerifyAll(); // No observers notified
        }
        public void ScenariosView_ChangeDikeProfileOfCalculation_ChangesCorrectlyObservedAndSynced()
        {
            // Setup
            using (var form = new Form())
            {
                var mocks           = new MockRepository();
                var messageProvider = mocks.Stub <IImporterMessageProvider>();
                mocks.ReplayAll();

                var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike);
                DataImportHelper.ImportReferenceLine(assessmentSection);
                GrassCoverErosionInwardsFailureMechanism failureMechanism = assessmentSection.GrassCoverErosionInwards;
                DataImportHelper.ImportFailureMechanismSections(assessmentSection, failureMechanism);

                var view = new GrassCoverErosionInwardsScenariosView(assessmentSection.GrassCoverErosionInwards.CalculationsGroup,
                                                                     assessmentSection.GrassCoverErosionInwards);
                form.Controls.Add(view);
                form.Show();

                var dikeProfilesImporter = new DikeProfilesImporter(assessmentSection.GrassCoverErosionInwards.DikeProfiles,
                                                                    assessmentSection.ReferenceLine, filePath,
                                                                    new GrassCoverErosionInwardsDikeProfileReplaceDataStrategy(failureMechanism),
                                                                    messageProvider);
                dikeProfilesImporter.Import();

                foreach (DikeProfile profile in assessmentSection.GrassCoverErosionInwards.DikeProfiles)
                {
                    assessmentSection.GrassCoverErosionInwards.CalculationsGroup.Children.Add(new GrassCoverErosionInwardsCalculationScenario
                    {
                        Name            = NamingHelper.GetUniqueName(assessmentSection.GrassCoverErosionInwards.CalculationsGroup.Children, profile.Name + "Calculation", c => c.Name),
                        InputParameters =
                        {
                            DikeProfile = profile
                        }
                    });
                }

                var listBox      = (ListBox) new ControlTester("listBox").TheObject;
                var dataGridView = (DataGridView) new ControlTester("dataGridView").TheObject;

                listBox.SelectedItem = failureMechanism.Sections.ElementAt(13);

                // Precondition
                DataGridViewRowCollection rows = dataGridView.Rows;
                Assert.AreEqual(1, rows.Count);
                Assert.AreEqual("profiel63p1NaamCalculation", rows[0].Cells[nameColumnIndex].FormattedValue);

                // Call
                CalculationGroup calculationsGroup = assessmentSection.GrassCoverErosionInwards.CalculationsGroup;
                ((GrassCoverErosionInwardsCalculationScenario)calculationsGroup.Children[1]).InputParameters.DikeProfile =
                    ((GrassCoverErosionInwardsCalculationScenario)calculationsGroup.Children[0]).InputParameters.DikeProfile;
                calculationsGroup.NotifyObservers();

                // Assert
                Assert.AreEqual(2, rows.Count);
                Assert.AreEqual("profiel63p1NaamCalculation", rows[0].Cells[nameColumnIndex].FormattedValue);
                Assert.AreEqual("profiel63p2NaamCalculation", rows[1].Cells[nameColumnIndex].FormattedValue);

                mocks.VerifyAll();
            }
        }