// 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_LogErrorAndReturnFalse()
{
// 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.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessage, LogLevelConstant.Error), 1);
Assert.IsFalse(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
const string expectedMessages = "Fout bij het lezen van kunstwerk op regel 1. Het kunstwerk heeft geen geldige waarde voor attribuut 'KWKIDENT'.";
TestHelper.AssertLogMessageWithLevelIsGenerated(call, Tuple.Create(expectedMessages, LogLevelConstant.Error), 1);
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 {}
}
}