// Copyright (C) Stichting Deltares 2023. All rights reserved.
//
// This file is part of the application DAM - UI.
//
// DAM - UI 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 Deltares.Dam.Data.StiImporter;
using Deltares.Geometry;
using GeometryCurve = Deltares.Geometry.GeometryCurve;
using Deltares.Geotechnics.Soils;
using Deltares.Standard.Logging;
using NUnit.Framework;
using GeometryLoop = Deltares.Geometry.GeometryLoop;
using GeometryPoint = Deltares.Geometry.GeometryPoint;
namespace Deltares.Dam.Tests.StiImporter
{
[TestFixture]
public class StiFileReaderTest
{
private const string TestDataFolder = @"TestData\StiImporter\";
[Test]
[TestCase(null)]
[TestCase("")]
[TestCase(" ")]
public void ReadSoilProfile_WithInvalidFilePath_ThrowsArgumentException(string invalidFilePath)
{
// Setup
var reader = new StiFileReader();
// Call
TestDelegate call = () => reader.ReadSoilProfile(invalidFilePath);
// Assert
Assert.That(call, Throws.ArgumentException
.With.Message.EqualTo("'filePath' cannot be null or consist of whitespaces only."));
}
[Test]
public void ReadSoilProfile_WithInvalidVersion_ThrowsStiFileReadException()
{
// Setup
LogManager.Messages.Clear(); // Clear the messages before the test starts as the log manager is a singleton.
string filePath = Path.Combine(TestDataFolder, "InvalidSoilVersion.sti");
var reader = new StiFileReader();
// Call
TestDelegate call = () => reader.ReadSoilProfile(filePath);
// Assert
Assert.That(call, Throws.Exception.TypeOf()
.With.Message.EqualTo($"'{filePath}' is an unsupported file."));
string expectedMessage = $"Soil data in '{filePath}' is of a version of D-Geo Stability that is not supported and cannot be read.";
CollectionAssert.AreEqual(new[]
{
expectedMessage
}, LogManager.Messages.Select(m => m.Message));
CollectionAssert.AreEqual(new[]
{
LogMessageType.Error
}, LogManager.Messages.Select(m => m.MessageType));
CollectionAssert.AreEqual(new[]
{
reader
}, LogManager.Messages.Select(m => m.Subject));
}
[Test]
public void ReadSoilProfile_WithValidFile_ReturnsExpectedSoilProfile()
{
// Setup
string filePath = Path.Combine(TestDataFolder, "SimpleProfile.sti");
var reader = new StiFileReader();
// Call
SoilProfile2D soilProfile = reader.ReadSoilProfile(filePath);
// Assert
Assert.That(soilProfile, Is.Not.Null);
Assert.That(soilProfile.Surfaces.Count, Is.EqualTo(2));
var topLeftPoint = new GeometryPoint(0, 0, -4);
var topRightPoint = new GeometryPoint(75, 0, -4);
var bottomLeftPoint = new GeometryPoint(0, 0, -6);
var bottomRightPoint = new GeometryPoint(75, 0, -6);
SoilLayer2D layerOne = soilProfile.Surfaces.ElementAt(0);
Assert.That(layerOne.Name, Is.EqualTo("Soft Clay"));
AssertSoilLayerGeometry(bottomLeftPoint, bottomRightPoint, topLeftPoint, topRightPoint, layerOne);
topLeftPoint = new GeometryPoint(0, 0, -2);
topRightPoint = new GeometryPoint(75, 0, -2);
bottomLeftPoint = new GeometryPoint(0, 0, -4);
bottomRightPoint = new GeometryPoint(75, 0, -4);
SoilLayer2D layerTwo = soilProfile.Surfaces.ElementAt(1);
Assert.That(layerTwo.Name, Is.EqualTo("Muck"));
AssertSoilLayerGeometry(bottomLeftPoint, bottomRightPoint, topLeftPoint, topRightPoint, layerTwo);
Assert.That(soilProfile.PreconsolidationStresses, Is.Empty);
}
[Test]
public void ReadSoilProfile_WithInvalidFile_ThrowsStiFileReadException()
{
// Setup
string filePath = Path.Combine(TestDataFolder, "SimpleProfileWithException.sti"); // This file contains more coordinates than the maximum specified
var reader = new StiFileReader();
// Call
TestDelegate call = () => reader.ReadSoilProfile(filePath);
// Assert
var exception = Assert.Throws(call);
Exception innerException = exception.InnerException;
Assert.That(innerException, Is.Not.Null);
Assert.That(exception.Message, Is.EqualTo($"Reading file '{filePath}' failed: {innerException.Message}."));
}
private static void AssertSoilLayerGeometry(GeometryPoint bottomLeftPoint,
GeometryPoint bottomRightPoint,
GeometryPoint topLeftPoint,
GeometryPoint topRightPoint,
SoilLayer2D layer)
{
GeometrySurface geometrySurface = layer.GeometrySurface;
Assert.That(geometrySurface.InnerLoops, Is.Empty); // Layers do not have inner loops
GeometryLoop actualGeometry = geometrySurface.OuterLoop;
var expectedPoints = new[]
{
bottomRightPoint,
bottomLeftPoint,
topLeftPoint,
topRightPoint
};
Assert.That(actualGeometry.Points.Count, Is.EqualTo(expectedPoints.Length));
for (int i = 0; i < expectedPoints.Length; i++)
{
GeometryPoint actualPoint = actualGeometry.Points[i];
Assert.That(actualPoint.LocationEquals(expectedPoints[i]), Is.True);
}
List curves = actualGeometry.CurveList;
var expectedCurves = new[]
{
new GeometryCurve(bottomLeftPoint, bottomRightPoint),
new GeometryCurve(bottomLeftPoint, topLeftPoint),
new GeometryCurve(topLeftPoint, topRightPoint),
new GeometryCurve(bottomRightPoint, topRightPoint)
};
int expectedNrOfCurves = expectedCurves.Length;
Assert.That(curves.Count, Is.EqualTo(expectedNrOfCurves));
for (int i = 0; i < expectedNrOfCurves; i++)
{
Assert.That(curves[i].LocationEquals(expectedCurves[i]), Is.True);
}
}
}
}