// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.IO; using System.Linq; using Core.Common.Base; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Core.Common.Base.IO; using Core.Common.TestUtil; using Core.Common.Utils.Builders; using NUnit.Framework; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.TestUtil; using Ringtoets.Common.IO.FileImporters; using Ringtoets.Common.IO.Structures; using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; namespace Ringtoets.Common.IO.Test.FileImporters { [TestFixture] public class StructuresImporterTest { private readonly ObservableList testImportTarget = new ObservableList(); private readonly ReferenceLine testReferenceLine = new ReferenceLine(); private readonly string testFilePath = string.Empty; [Test] public void Constructor_Always_ExpectedValues() { // Call var importer = new TestStructuresImporter(testImportTarget, testReferenceLine, testFilePath); // Assert Assert.IsInstanceOf(importer); } [Test] public void Constructor_ImportTargetNull_ThrowArgumentNullException() { // Call TestDelegate call = () => new TestStructuresImporter(null, testReferenceLine, testFilePath); // Assert var exception = Assert.Throws(call); Assert.AreEqual("importTarget", exception.ParamName); } [Test] public void Constructor_ReferenceLineNull_ThrowArgumentNullException() { // Call TestDelegate call = () => new TestStructuresImporter(testImportTarget, null, testFilePath); // Assert var exception = Assert.Throws(call); Assert.AreEqual("referenceLine", exception.ParamName); } [Test] public void Constructor_FilePathNull_ThrowArgumentNullException() { // Call TestDelegate call = () => new TestStructuresImporter(testImportTarget, testReferenceLine, null); // Assert var exception = Assert.Throws(call); Assert.AreEqual("filePath", exception.ParamName); } [Test] [TestCase("")] [TestCase(" ")] public void Import_FromInvalidEmptyPath_FalseAndLogError(string filePath) { // Setup var testStructuresImporter = new TestStructuresImporter(testImportTarget, testReferenceLine, filePath); // Call var importResult = true; Action call = () => importResult = testStructuresImporter.Import(); // Assert TestHelper.AssertLogMessages(call, messages => { string[] messageArray = messages.ToArray(); string expectedMessage = new FileReaderErrorMessageBuilder(filePath) .Build(CoreCommonUtilsResources.Error_Path_must_be_specified); StringAssert.StartsWith(expectedMessage, messageArray[0]); }); Assert.IsFalse(importResult); } [Test] public void Import_FromPathContainingInvalidPathCharacters_FalseAndLogError() { // Setup const string filePath = "c:\\Invalid_Characters.shp"; char[] invalidPathChars = Path.GetInvalidPathChars(); string invalidPath = filePath.Replace('_', invalidPathChars[0]); var testStructuresImporter = new TestStructuresImporter(testImportTarget, testReferenceLine, invalidPath); // Call var importResult = true; Action call = () => importResult = testStructuresImporter.Import(); // Assert TestHelper.AssertLogMessages(call, messages => { string message = messages.First(); string expectedMessage = new FileReaderErrorMessageBuilder(invalidPath) .Build("Er zitten ongeldige tekens in het bestandspad. Alle tekens in het bestandspad moeten geldig zijn."); StringAssert.StartsWith(expectedMessage, message); }); Assert.IsFalse(importResult); } [Test] public void Import_FromDirectoryPath_FalseAndLogError() { // Setup string folderPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO) + Path.DirectorySeparatorChar; var testStructuresImporter = new TestStructuresImporter(testImportTarget, testReferenceLine, folderPath); // Call var importResult = true; Action call = () => importResult = testStructuresImporter.Import(); // Assert string expectedMessage = new FileReaderErrorMessageBuilder(folderPath) .Build(CoreCommonUtilsResources.Error_Path_must_not_point_to_empty_file_name); TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1); Assert.IsFalse(importResult); } [Test] [TestCase("Multiple_Polygon_with_ID.shp")] [TestCase("Multiple_PolyLine_with_ID.shp")] [TestCase("Single_Multi-Polygon_with_ID.shp")] [TestCase("Single_Multi-PolyLine_with_ID.shp")] [TestCase("Single_Polygon_with_ID.shp")] [TestCase("Single_PolyLine_with_ID.shp")] public void Import_FromFileWithNonPointFeatures_FalseAndLogError(string shapeFileName) { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Core.Components.Gis.IO, shapeFileName); var profilesImporter = new TestStructuresImporter(testImportTarget, testReferenceLine, filePath); // Call var importResult = true; Action call = () => importResult = profilesImporter.Import(); // Assert string expectedMessage = string.Format("Fout bij het lezen van bestand '{0}': kon geen punten vinden in dit bestand.", filePath); TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1); Assert.IsFalse(importResult); } [Test] public void Import_InvalidShapefile_ReturnsFalse() { // Setup string invalidFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "StructuresWithoutKWKIDENT", "Kunstwerken.shp")); var profilesImporter = new TestStructuresImporter(testImportTarget, testReferenceLine, invalidFilePath); // Call bool importResult = profilesImporter.Import(); // Assert Assert.IsFalse(importResult); } [Test] public void Import_InvalidCsvFile_ReturnsFalse() { // Setup string invalidFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectShpIncorrectCsv", "CorrectKunstwerken_IncorrectCsv.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var profilesImporter = new TestStructuresImporter(testImportTarget, referenceLine, invalidFilePath); // Call bool importResult = profilesImporter.Import(); // Assert Assert.IsFalse(importResult); } [Test] public void Import_CancelOfImportWhenReadingLocations_CancelsImportAndLogs() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var importTarget = new ObservableList(); var testStructuresImporter = new TestStructuresImporter(importTarget, referenceLine, filePath); testStructuresImporter.SetProgressChanged((description, step, steps) => { if (description.Contains("Inlezen van kunstwerklocaties uit een shapebestand.")) { testStructuresImporter.Cancel(); } }); var importResult = true; // Call Action call = () => importResult = testStructuresImporter.Import(); // Assert TestHelper.AssertLogMessageIsGenerated(call, "Kunstwerken importeren is afgebroken. Geen gegevens ingelezen."); Assert.IsFalse(importResult); } [Test] public void Import_CancelOfImportWhenCreatingStructures_ContinuesImportAndLogs() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var importTarget = new ObservableList(); var testStructuresImporter = new TestStructuresImporter(importTarget, referenceLine, filePath); testStructuresImporter.SetProgressChanged((description, step, steps) => { if (description.Contains("Geïmporteerde data toevoegen aan het toetsspoor.")) { testStructuresImporter.Cancel(); } }); var importResult = true; // Call Action call = () => importResult = testStructuresImporter.Import(); // Assert TestHelper.AssertLogMessageIsGenerated(call, "Huidige actie was niet meer te annuleren en is daarom voortgezet."); Assert.IsTrue(importResult); } [Test] public void Import_CancelOfImportWhenReadingStructureData_ReturnsFalse() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var importTarget = new ObservableList(); var testStructuresImporter = new TestStructuresImporter(importTarget, referenceLine, filePath); testStructuresImporter.SetProgressChanged((description, step, steps) => { if (description.Contains("Inlezen van kunstwerkgegevens uit een kommagescheiden bestand.")) { testStructuresImporter.Cancel(); } }); var importResult = true; // Call Action call = () => importResult = testStructuresImporter.Import(); // Assert TestHelper.AssertLogMessageIsGenerated(call, "Kunstwerken importeren is afgebroken. Geen gegevens ingelezen."); Assert.IsFalse(importResult); } [Test] public void Import_ReuseOfCanceledImportToValidTargetWithValidFile_ReturnsTrue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var importTarget = new ObservableList(); var testStructuresImporter = new TestStructuresImporter(importTarget, referenceLine, filePath); testStructuresImporter.SetProgressChanged((description, step, steps) => testStructuresImporter.Cancel()); bool importResult = testStructuresImporter.Import(); // Precondition Assert.IsFalse(importResult); testStructuresImporter.SetProgressChanged(null); // Call importResult = testStructuresImporter.Import(); // Assert Assert.IsTrue(importResult); } [Test] public void Import_LocationOutsideReferenceLine_LogErrorAndReturnTrue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var testStructuresImporter = new TestStructuresImporter(new ObservableList(), referenceLine, filePath); // Call var importResult = true; Action call = () => importResult = testStructuresImporter.Import(); // Assert TestHelper.AssertLogMessages(call, messages => { string[] messageArray = messages.ToArray(); const string expectedMessage = "Een kunstwerklocatie met KWKIDENT 'KUNST6' ligt niet op de referentielijn. Locatie wordt overgeslagen."; StringAssert.StartsWith(expectedMessage, messageArray[0]); }); Assert.IsTrue(importResult); } [Test] public void Import_DuplicateLocation_LogWarningAndReturnTrue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "DuplicateLocation", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var testStructuresImporter = new TestStructuresImporter(new ObservableList(), referenceLine, filePath); // Call var importResult = true; Action call = () => importResult = testStructuresImporter.Import(); // Assert const string expectedMessage = "Kunstwerklocatie met KWKIDENT 'KUNST3' is opnieuw ingelezen."; TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1); Assert.IsTrue(importResult); } [Test] public void Import_LocationKWKIDENTNull_LogErrorAndReturnFalse() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "StructuresWithNullKWKident", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var testStructuresImporter = new TestStructuresImporter(new ObservableList(), referenceLine, filePath); // Call var importResult = true; Action call = () => importResult = testStructuresImporter.Import(); // Assert string[] expectedMessages = { "Fout bij het lezen van kunstwerk op regel 1. Het kunstwerk heeft geen geldige waarde voor attribuut 'KWKIDENT'. Dit kunstwerk wordt overgeslagen.", "Fout bij het lezen van kunstwerk op regel 2. Het kunstwerk heeft geen geldige waarde voor attribuut 'KWKIDENT'. Dit kunstwerk wordt overgeslagen.", "Fout bij het lezen van kunstwerk op regel 3. Het kunstwerk heeft geen geldige waarde voor attribuut 'KWKIDENT'. Dit kunstwerk wordt overgeslagen.", "Fout bij het lezen van kunstwerk op regel 4. Het kunstwerk heeft geen geldige waarde voor attribuut 'KWKIDENT'. Dit kunstwerk wordt overgeslagen.", "Fout bij het lezen van kunstwerk op regel 5. Het kunstwerk heeft geen geldige waarde voor attribuut 'KWKIDENT'. Dit kunstwerk wordt overgeslagen." }; TestHelper.AssertLogMessagesAreGenerated(call, expectedMessages); Assert.IsFalse(importResult); } [Test] public void Import_IllegalCsvFile_ReturnsFalse() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "IllegalCsv", "Kunstwerken.shp")); var referencePoints = new List { new Point2D(131144.094, 549979.893), new Point2D(131538.705, 548316.752), new Point2D(135878.442, 532149.859), new Point2D(131225.017, 548395.948), new Point2D(131270.38, 548367.462), new Point2D(131507.119, 548322.951) }; var referenceLine = new ReferenceLine(); referenceLine.SetGeometry(referencePoints); var testStructuresImporter = new TestStructuresImporter(new ObservableList(), referenceLine, filePath); // Call bool importResult = testStructuresImporter.Import(); // Assert Assert.IsFalse(importResult); } [Test] public void GetStandardDeviation_RowHasStandardDeviation_ReturnVarianceValue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referenceLine = new ReferenceLine(); var importTarget = new ObservableList(); var importer = new TestStructuresImporter(importTarget, referenceLine, filePath); var parameter = new StructuresParameterRow { AlphanumericValue = "", LineNumber = 3, LocationId = "A", NumericalValue = -2, ParameterId = "B", VarianceType = VarianceType.StandardDeviation, VarianceValue = 1.2 }; // Call var standardDeviation = (RoundedDouble) 0.0; Action call = () => standardDeviation = importer.GetStandardDeviation(parameter, ""); // Assert TestHelper.AssertLogMessagesCount(call, 0); Assert.AreEqual(parameter.VarianceValue, standardDeviation, standardDeviation.GetAccuracy()); } [Test] public void GetStandardDeviation_RowHasCoefficientOfVariation_ReturnConvertedVarianceValue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referenceLine = new ReferenceLine(); var importTarget = new ObservableList(); var importer = new TestStructuresImporter(importTarget, referenceLine, filePath); var parameter = new StructuresParameterRow { AlphanumericValue = "", LineNumber = 3, LocationId = "A", NumericalValue = -2, ParameterId = "B", VarianceType = VarianceType.CoefficientOfVariation, VarianceValue = 1.2 }; const string structureName = ""; // Call var standardDeviation = (RoundedDouble) 0.0; Action call = () => standardDeviation = importer.GetStandardDeviation(parameter, structureName); // Assert string message = string.Format("De variatie voor parameter '{2}' van kunstwerk '{0}' ({1}) wordt omgerekend in een standaardafwijking (regel {3}).", structureName, parameter.LocationId, parameter.ParameterId, parameter.LineNumber); TestHelper.AssertLogMessageIsGenerated(call, message, 1); double expectedStandardDeviation = parameter.VarianceValue * Math.Abs(parameter.NumericalValue); Assert.AreEqual(expectedStandardDeviation, standardDeviation, standardDeviation.GetAccuracy()); } [Test] public void GetCoefficientOfVariation_RowHasCoefficientOfVariation_ReturnVarianceValue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referenceLine = new ReferenceLine(); var importTarget = new ObservableList(); var importer = new TestStructuresImporter(importTarget, referenceLine, filePath); var parameter = new StructuresParameterRow { AlphanumericValue = "", LineNumber = 3, LocationId = "A", NumericalValue = -3, ParameterId = "B", VarianceType = VarianceType.CoefficientOfVariation, VarianceValue = 2.3 }; // Call var coefficientOfVariation = (RoundedDouble) 0.0; Action call = () => coefficientOfVariation = importer.GetCoefficientOfVariation(parameter, ""); // Assert TestHelper.AssertLogMessagesCount(call, 0); Assert.AreEqual(parameter.VarianceValue, coefficientOfVariation, coefficientOfVariation.GetAccuracy()); } [Test] public void GetCoefficientOfVariation_RowHasStandardDeviation_ReturnConvertedVarianceValue() { // Setup string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp")); var referenceLine = new ReferenceLine(); var importTarget = new ObservableList(); var importer = new TestStructuresImporter(importTarget, referenceLine, filePath); var parameter = new StructuresParameterRow { AlphanumericValue = "", LineNumber = 3, LocationId = "A", NumericalValue = -3, ParameterId = "B", VarianceType = VarianceType.StandardDeviation, VarianceValue = 2.3 }; const string structureName = ""; // Call var coefficientOfVariation = (RoundedDouble) 0.0; Action call = () => coefficientOfVariation = importer.GetCoefficientOfVariation(parameter, structureName); // Assert string message = string.Format("De variatie voor parameter '{2}' van kunstwerk '{0}' ({1}) wordt omgerekend in een variatiecoëfficiënt (regel {3}).", structureName, parameter.LocationId, parameter.ParameterId, parameter.LineNumber); TestHelper.AssertLogMessageIsGenerated(call, message, 1); double expectedStandardDeviation = parameter.VarianceValue / Math.Abs(parameter.NumericalValue); Assert.AreEqual(expectedStandardDeviation, coefficientOfVariation, coefficientOfVariation.GetAccuracy()); } private class TestStructuresImporter : StructuresImporter> { public TestStructuresImporter(ObservableList importTarget, ReferenceLine referenceLine, string filePath) : base(importTarget, referenceLine, filePath) {} public new RoundedDouble GetStandardDeviation(StructuresParameterRow parameter, string structureName) { return base.GetStandardDeviation(parameter, structureName); } public new RoundedDouble GetCoefficientOfVariation(StructuresParameterRow parameter, string structureName) { return base.GetCoefficientOfVariation(parameter, structureName); } protected override void CreateSpecificStructures(ICollection structureLocations, Dictionary> groupedStructureParameterRows) {} } private class TestStructure {} } }