// 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.Geometry;
using Core.Common.Base.IO;
using Core.Common.TestUtil;
using NUnit.Framework;
using Rhino.Mocks;
using Ringtoets.Common.Data.AssessmentSection;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.FailureMechanism;
using Ringtoets.Common.IO.FileImporters;
using Ringtoets.Common.IO.ReferenceLines;
namespace Ringtoets.Common.IO.Test.FileImporters
{
[TestFixture]
public class FailureMechanismSectionsImporterTest
{
[Test]
public void Constructor_FailureMechanismNull_ThrowArgumentNullException()
{
// Setup
var referenceLine = new ReferenceLine();
// Call
TestDelegate call = () => new FailureMechanismSectionsImporter(null, referenceLine, "");
// Assert
string paramName = Assert.Throws(call).ParamName;
Assert.AreEqual("importTarget", paramName);
}
[Test]
public void Constructor_ReferenceLineNull_ThrowsArgumentNullException()
{
// Setup
var mocks = new MockRepository();
var failureMechanism = mocks.Stub();
mocks.ReplayAll();
// Call
TestDelegate call = () => new FailureMechanismSectionsImporter(failureMechanism, null, "");
// Assert
string paramName = Assert.Throws(call).ParamName;
Assert.AreEqual("referenceLine", paramName);
mocks.VerifyAll();
}
[Test]
public void Constructor_ExpectedValues()
{
// Setup
var mocks = new MockRepository();
var failureMechanism = mocks.Stub();
mocks.ReplayAll();
var referenceLine = new ReferenceLine();
// Call
var importer = new FailureMechanismSectionsImporter(failureMechanism, referenceLine, "");
// Assert
Assert.IsInstanceOf>(importer);
mocks.VerifyAll();
}
[Test]
[TestCase("traject_1-1.shp", "traject_1-1_vakken.shp", 62)]
[TestCase("traject_19-1.shp", "traject_19-1_vakken.shp", 17)]
public void Import_ValidFileCorrespondingToReferenceLineAndNoSectionImportedYet_ImportSections(string referenceLineFileName, string sectionsFileName, int sectionCount)
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", referenceLineFileName));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", sectionsFileName));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
var importSuccessful = importer.Import();
// Assert
Assert.IsTrue(importSuccessful);
FailureMechanismSection[] sections = failureMechanism.Sections.ToArray();
Assert.AreEqual(sectionCount, sections.Length);
AssertSectionsAreValidForReferenceLine(sections, assessmentSection.ReferenceLine);
mocks.VerifyAll();
}
[Test]
public void Import_ValidFileCorrespondingToReferenceLineAndHasSectionImported_ReplaceSections()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "traject_1-1.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "traject_1-1_vakken.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
failureMechanism.AddSection(new FailureMechanismSection("A", assessmentSection.ReferenceLine.Points));
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
var importSuccessful = importer.Import();
// Assert
Assert.IsTrue(importSuccessful);
FailureMechanismSection[] sections = failureMechanism.Sections.ToArray();
Assert.AreEqual(62, sections.Length);
AssertSectionsAreValidForReferenceLine(sections, assessmentSection.ReferenceLine);
mocks.VerifyAll();
}
[Test]
public void Import_ValidArtificialFileImperfectlyCorrespondingToReferenceLineAndNoSectionImportedYet_ImportSections()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "Artificial_referencelijn_testA_ValidVakken.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
var importSuccessful = importer.Import();
// Assert
Assert.IsTrue(importSuccessful);
FailureMechanismSection[] sections = failureMechanism.Sections.ToArray();
Assert.AreEqual(7, sections.Length);
AssertSectionsAreValidForReferenceLine(sections, assessmentSection.ReferenceLine);
mocks.VerifyAll();
}
[Test]
public void Import_ValidImport_GenerateExpectedProgressMessages()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "Artificial_referencelijn_testA_ValidVakken.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var progressChangeNotifications = new List();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
importer.SetProgressChanged((description, step, steps) => progressChangeNotifications.Add(new ProgressNotification(description, step, steps)));
// Call
var importSuccessful = importer.Import();
// Assert
Assert.IsTrue(importSuccessful);
var expectedProgressMessages = new[]
{
new ProgressNotification("Inlezen vakindeling.", 1, 3),
new ProgressNotification("Valideren ingelezen vakindeling.", 2, 3),
new ProgressNotification("Geïmporteerde gegevens toevoegen aan het toetsspoor.", 3, 3)
};
Assert.AreEqual(expectedProgressMessages.Length, progressChangeNotifications.Count);
for (int i = 0; i < expectedProgressMessages.Length; i++)
{
var notification = expectedProgressMessages[i];
var actualNotification = progressChangeNotifications[i];
Assert.AreEqual(notification.Text, actualNotification.Text);
Assert.AreEqual(notification.CurrentStep, actualNotification.CurrentStep);
Assert.AreEqual(notification.TotalSteps, actualNotification.TotalSteps);
}
mocks.VerifyAll();
}
[Test]
public void Import_FilePathIsDirectory_CancelImportWithErrorMessage()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "traject_1-1.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, Path.DirectorySeparatorChar.ToString());
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = string.Format(@"Fout bij het lezen van bestand '{0}': Bestandspad mag niet verwijzen naar een lege bestandsnaam. ", sectionsFilePath) + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
public void Import_FileDoesNotExist_CancelImportWithErrorMessage()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "traject_1-1.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO, "I_dont_exist.shp");
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage =
string.Format(@"Fout bij het lezen van bestand '{0}': Het bestand bestaat niet. ", sectionsFilePath) + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
public void Import_EmptyArtificialFile_CancelImportWithErrorMessage()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "Artificial_referencelijn_testA_EmptyVakken.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = "Het bestand heeft geen vakindeling. " + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
[TestCase("StartTooFarFromReferenceline")]
[TestCase("EndTooFarFromReferenceline")]
public void Import_InvalidArtificialFileBecauseOfStartEndPointsTooFarFromReferenceLine_CancelImportWithErrorMessage(string shapeCondition)
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var shapeFileName = string.Format("Artificial_referencelijn_testA_InvalidVakken_Section{0}.shp", shapeCondition);
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", shapeFileName));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = "Vakindeling komt niet overeen met de huidige referentielijn. " + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
[TestCase("StartTooFarFromReferencelineStart")]
[TestCase("EndTooFarFromReferencelineEnd")]
public void Import_InvalidArtificialFileBecauseOfStartEndPointsTooFarFromStartEndOfReferenceLine_CancelImportWithErrorMessage(string shapeCondition)
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var shapeFileName = string.Format("Artificial_referencelijn_testA_InvalidVakken_{0}.shp", shapeCondition);
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", shapeFileName));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = "Vakindeling komt niet overeen met de huidige referentielijn. " + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
public void Import_InvalidArtificialFileBecauseSectionsDoNotFullyCoverReferenceLine_CancelImportWithErrorMessage()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "Artificial_referencelijn_testA_InvalidVakken_NotCoveringWholeReferenceLine.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = "Vakindeling komt niet overeen met de huidige referentielijn. " + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
public void Import_InvalidArtificialFileBecauseSomePointsNotOnReferenceLine_CancelImportWithErrorMessage()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "Artificial_referencelijn_testA.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "Artificial_referencelijn_testA_InvalidVakken_PointsTooFarFromReferenceLine.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = "Vakindeling komt niet overeen met de huidige referentielijn. " + Environment.NewLine +
"Er is geen vakindeling geïmporteerd.";
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
mocks.VerifyAll();
}
[Test]
public void Import_MissingNameValue_CancelImportWithErrorMessage()
{
// Setup
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "vakindeling_Empty_Name_Value.shp"));
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, new ReferenceLine(), sectionsFilePath);
// Call
bool importSuccessful = true;
Action call = () => importSuccessful = importer.Import();
// Assert
var expectedMessage = string.Format(
"Fout bij het lezen van bestand '{0}': Voor één van de vakken is geen naam opgegeven. {1}Er is geen vakindeling geïmporteerd.",
sectionsFilePath,
Environment.NewLine);
TestHelper.AssertLogMessageIsGenerated(call, expectedMessage, 1);
Assert.IsFalse(importSuccessful);
CollectionAssert.IsEmpty(failureMechanism.Sections);
}
[Test]
public void Import_ValidFileImportBeingCancelled_CancelImportWithInfoMessage()
{
// Setup
var referenceLineFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("ReferenceLine", "traject_1-1.shp"));
var sectionsFilePath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Common.IO,
Path.Combine("FailureMechanismSections", "traject_1-1_vakken.shp"));
var mocks = new MockRepository();
var assessmentSection = mocks.Stub();
mocks.ReplayAll();
var referenceLineImporter = new ReferenceLineImporter(assessmentSection, referenceLineFilePath);
referenceLineImporter.Import();
var failureMechanism = new Simple();
var importer = new FailureMechanismSectionsImporter(failureMechanism, assessmentSection.ReferenceLine, sectionsFilePath);
importer.Cancel();
Assert.IsFalse(importer.Import());
// Call
var importSuccessful = importer.Import();
// Assert
Assert.IsTrue(importSuccessful);
FailureMechanismSection[] sections = failureMechanism.Sections.ToArray();
Assert.AreEqual(62, sections.Length);
AssertSectionsAreValidForReferenceLine(sections, assessmentSection.ReferenceLine);
mocks.VerifyAll();
}
private void AssertSectionsAreValidForReferenceLine(FailureMechanismSection[] sections, ReferenceLine referenceLine)
{
Point2D[] referenceLineGeometry = referenceLine.Points.ToArray();
// 1. Start & End coherence:
Assert.AreEqual(referenceLineGeometry[0], sections[0].GetStart(),
"Start of the sections should correspond to the Start of the reference line.");
Assert.AreEqual(referenceLineGeometry[referenceLineGeometry.Length - 1], sections[sections.Length - 1].GetLast(),
"End of the sections should correspond to the End of the reference line.");
// 2. Total length coherence:
var totalLengthOfSections = sections.Sum(s => GetLengthOfLine(s.Points));
var totalLengthOfReferenceLine = GetLengthOfLine(referenceLineGeometry);
Assert.AreEqual(totalLengthOfReferenceLine, totalLengthOfSections, 1e-6,
"The length of all sections should sum up to the length of the reference line.");
// 3. Section Start and End coherence
IEnumerable allStartAndEndPoints = sections.Select(s => s.GetStart()).Concat(sections.Select(s => s.GetLast()));
foreach (Point2D point in allStartAndEndPoints)
{
Assert.Less(GetDistanceToReferenceLine(point, referenceLine), 1e-6,
"All start- and end points should be on the reference line.");
}
// 4. Section Start and End points coherence
FailureMechanismSection sectionTowardsEnd = null;
foreach (FailureMechanismSection section in sections)
{
FailureMechanismSection sectionTowardsStart = sectionTowardsEnd;
sectionTowardsEnd = section;
if (sectionTowardsStart != null)
{
Assert.AreEqual(sectionTowardsStart.GetLast(), sectionTowardsEnd.GetStart(),
"All sections should be connected and in order of connectedness.");
}
}
}
private double GetDistanceToReferenceLine(Point2D point, ReferenceLine referenceLine)
{
return GetLineSegments(referenceLine.Points)
.Select(segment => segment.GetEuclideanDistanceToPoint(point))
.Min();
}
private double GetLengthOfLine(IEnumerable linePoints)
{
return GetLineSegments(linePoints).Sum(segment => segment.Length);
}
private IEnumerable GetLineSegments(IEnumerable linePoints)
{
Point2D endPoint = null;
foreach (Point2D linePoint in linePoints)
{
Point2D startPoint = endPoint;
endPoint = linePoint;
if (startPoint != null)
{
yield return new Segment2D(startPoint, endPoint);
}
}
}
private class Simple : FailureMechanismBase
{
public Simple() : base("Stubbed name", "Stubbed code") {}
public override IEnumerable Calculations
{
get
{
throw new NotImplementedException();
}
}
}
private class ProgressNotification
{
public ProgressNotification(string description, int currentStep, int totalSteps)
{
Text = description;
CurrentStep = currentStep;
TotalSteps = totalSteps;
}
public string Text { get; private set; }
public int CurrentStep { get; private set; }
public int TotalSteps { get; private set; }
}
}
}