// Copyright (C) Stichting Deltares 2016. 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_FromPathContainingInvalidFileCharacters_FalseAndLogError()
{
// Setup
string filePath = "c:\\Invalid_Characters.shp";
var invalidFileNameChars = Path.GetInvalidFileNameChars();
var invalidPath = filePath.Replace('_', invalidFileNameChars[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(string.Format(CoreCommonUtilsResources.Error_Path_cannot_contain_Characters_0_, string.Join(", ", invalidFileNameChars)));
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);
}
[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);
}
[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
var 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)
};
ReferenceLine referenceLine = new ReferenceLine();
referenceLine.SetGeometry(referencePoints);
var profilesImporter = new TestStructuresImporter(testImportTarget, referenceLine, invalidFilePath);
// Call
var importResult = profilesImporter.Import();
// Assert
Assert.IsFalse(importResult);
}
[Test]
public void Import_CancelOfImportToValidTargetWithValidFile_ReturnsFalse()
{
// Setup
string filePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Integration.Plugin,
Path.Combine("Structures", "CorrectFiles", "Kunstwerken.shp"));
var testStructuresImporter = new TestStructuresImporter(testImportTarget, testReferenceLine, filePath);
testStructuresImporter.Cancel();
// Call
bool importResult = testStructuresImporter.Import();
// Assert
Assert.IsFalse(importResult);
}
[Test]
public void Import_ReuseOfCancelledImportToValidTargetWithValidFile_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)
};
ReferenceLine referenceLine = new ReferenceLine();
referenceLine.SetGeometry(referencePoints);
var importTarget = new ObservableList();
var testStructuresImporter = new TestStructuresImporter(importTarget, referenceLine, filePath);
testStructuresImporter.Cancel();
bool importResult = testStructuresImporter.Import();
// Precondition
Assert.IsFalse(importResult);
// 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)
};
ReferenceLine 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();
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)
};
ReferenceLine 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 expectedMessage = "Kunstwerklocatie met KWKIDENT 'KUNST3' is opnieuw ingelezen.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
}
[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)
};
ReferenceLine 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);
}
[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)
};
ReferenceLine referenceLine = new ReferenceLine();
referenceLine.SetGeometry(referencePoints);
var testStructuresImporter = new TestStructuresImporter(new ObservableList(), referenceLine, filePath);
// Call
var 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"));
ReferenceLine 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
RoundedDouble 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"));
ReferenceLine 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
RoundedDouble 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 standaard deviatie (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"));
ReferenceLine 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
RoundedDouble 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"));
ReferenceLine 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
RoundedDouble 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 {}
}
}