// 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.Linq;
using Core.Common.Base.Geometry;
using NUnit.Framework;
using Ringtoets.Common.IO.Exceptions;
using Ringtoets.Common.IO.SoilProfile;
using Ringtoets.Common.IO.TestUtil;
using Ringtoets.Piping.Data.TestUtil;
using Ringtoets.Piping.IO.SoilProfiles;
using Ringtoets.Piping.Primitives;
namespace Ringtoets.Piping.IO.Test.SoilProfiles
{
[TestFixture]
public class PipingSoilProfileTransformerTest
{
[Test]
public void Transform_SoilProfileNull_ThrowsArgumentNullException()
{
// Call
TestDelegate test = () => PipingSoilProfileTransformer.Transform(null);
// Assert
var exception = Assert.Throws(test);
Assert.AreEqual("soilProfile", exception.ParamName);
}
[Test]
public void Transform_InvalidSoilProfile_ThrowsImportedDataTransformException()
{
// Setup
var invalidType = new TestSoilProfile();
// Call
TestDelegate test = () => PipingSoilProfileTransformer.Transform(invalidType);
// Assert
var exception = Assert.Throws(test);
const string message = "De ondergrondschematisatie van het type 'TestSoilProfile' is niet ondersteund. " +
"Alleen ondergrondschematisaties van het type 'SoilProfile1D' of 'SoilProfile2D' zijn ondersteund.";
Assert.AreEqual(message, exception.Message);
}
[Test]
public void Transform_SoilProfile2DWithoutIntersection_ThrowsImportedDataTransformException()
{
// Setup
const string name = "name";
var profile = new SoilProfile2D(0, name, new[]
{
new SoilLayer2D(new SoilLayer2DLoop(new Segment2D[0]), Enumerable.Empty())
}, Enumerable.Empty());
// Call
TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile);
// Assert
var exception = Assert.Throws(test);
Assert.AreEqual($"Geen geldige X waarde gevonden om intersectie te maken uit 2D profiel '{name}'.",
exception.Message);
}
[Test]
public void Transform_ValidSoilProfile2D_ReturnsExpectedPipingSoilProfile()
{
// Setup
const string name = "name";
const double bottom = 0.5;
const double intersectionX = 1.0;
SoilLayer2D layer = SoilLayer2DTestFactory.CreateSoilLayer2D(new List(),
new List
{
new Segment2D(new Point2D(1.0, bottom),
new Point2D(1.2, 1)),
new Segment2D(new Point2D(1.2, 1),
new Point2D(1.0, bottom))
});
var profile = new SoilProfile2D(0, name, new[]
{
layer
}, Enumerable.Empty())
{
IntersectionX = intersectionX
};
// Call
PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile);
// Assert
Assert.AreEqual(name, transformed.Name);
Assert.AreEqual(SoilProfileType.SoilProfile2D, transformed.SoilProfileSourceType);
Assert.AreEqual(bottom, transformed.Bottom);
double bottomOut;
IEnumerable actualPipingSoilLayers = PipingSoilLayerTransformer.Transform(
layer, intersectionX, out bottomOut);
AssertPipingSoilLayers(actualPipingSoilLayers, transformed.Layers);
}
[Test]
public void Transform_SoilProfile2DLayerWithVerticalLineOnXInXml_ThrowsImportedDataTransformException()
{
// Setup
const string profileName = "SomeProfile";
const double atX = 0.0;
SoilLayer2D layer = SoilLayer2DTestFactory.CreateSoilLayer2D(
new List(),
new List
{
new Segment2D(new Point2D(atX, 0.0),
new Point2D(atX, 1.0)),
new Segment2D(new Point2D(atX, 1.0),
new Point2D(0.5, 0.5)),
new Segment2D(new Point2D(0.5, 0.5),
new Point2D(atX, 0.0))
});
var profile = new SoilProfile2D(0, profileName, new[]
{
layer
}, Enumerable.Empty())
{
IntersectionX = atX
};
// Call
TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile);
// Assert
var exception = Assert.Throws(test);
string message = "Er kan geen 1D-profiel bepaald worden wanneer segmenten in een 2D " +
$"laag verticaal lopen op de gekozen positie: x = {atX}.";
Assert.AreEqual(message, exception.Message);
}
[Test]
public void Transform_SoilProfile2DWithoutIntersectionX_ThrowsImportedDataTransformException()
{
// Setup
const string profileName = "SomeProfile";
var profile = new SoilProfile2D(0, profileName, new[]
{
new SoilLayer2D(new SoilLayer2DLoop(new Segment2D[0]), Enumerable.Empty())
}, Enumerable.Empty());
// Call
TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = $"Geen geldige X waarde gevonden om intersectie te maken uit 2D profiel '{profileName}'.";
Assert.AreEqual(expectedMessage, exception.Message);
}
[Test]
public void Transform_InvalidSoilProfile2D_ThrowsImportedDataTransformException()
{
// Setup
var random = new Random(21);
var profile = new SoilProfile2D(0, string.Empty, Enumerable.Empty(), Enumerable.Empty())
{
IntersectionX = random.NextDouble()
};
// Call
TestDelegate test = () => PipingSoilProfileTransformer.Transform(profile);
// Assert
var exception = Assert.Throws(test);
Exception innerException = exception.InnerException;
Assert.IsInstanceOf(innerException);
Assert.AreEqual(innerException.Message, exception.Message);
}
[Test]
public void Transform_SoilProfile2DWithSingleLayerOnlyOuterLoop_ReturnsProfileWithBottomAndALayer()
{
// Setup
const string profileName = "SomeProfile";
var firstPoint = new Point2D(-0.5, 1.0);
var secondPoint = new Point2D(0.5, 1.0);
var thirdPoint = new Point2D(0.5, -1.0);
var fourthPoint = new Point2D(-0.5, -1.0);
SoilLayer2D layer = SoilLayer2DTestFactory.CreateSoilLayer2D(
new List(),
new List
{
new Segment2D(firstPoint, secondPoint),
new Segment2D(secondPoint, thirdPoint),
new Segment2D(thirdPoint, fourthPoint),
new Segment2D(fourthPoint, firstPoint)
});
var profile = new SoilProfile2D(0, profileName, new[]
{
layer
}, Enumerable.Empty())
{
IntersectionX = 0.0
};
// Call
PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile);
// Assert
Assert.AreEqual(profileName, transformed.Name);
Assert.AreEqual(1, transformed.Layers.Count());
Assert.AreEqual(1.0, transformed.Layers.ToArray()[0].Top);
Assert.AreEqual(-1.0, transformed.Bottom);
Assert.AreEqual(SoilProfileType.SoilProfile2D, transformed.SoilProfileSourceType);
}
[Test]
public void Transform_SoilProfile2DWithMultipleLayersOnlyOuterLoop_ReturnsProfileWithBottomAndALayers()
{
// Setup
const string profileName = "SomeProfile";
const long pipingSoilProfileId = 1234L;
var profile = new SoilProfile2D(pipingSoilProfileId, profileName,
new List
{
SoilLayer2DTestFactory.CreateSoilLayer2D(
new List(),
Segment2DLoopCollectionHelper.CreateFromString(
string.Join(Environment.NewLine,
"10",
"...",
"...",
"...",
"...",
"...",
"...",
"...",
"1.2",
"4.3",
"..."))),
SoilLayer2DTestFactory.CreateSoilLayer2D(
new List(),
Segment2DLoopCollectionHelper.CreateFromString(
string.Join(Environment.NewLine,
"10",
"...",
"...",
"...",
"...",
"...",
"4.3",
"...",
"1.2",
"...",
"..."))),
SoilLayer2DTestFactory.CreateSoilLayer2D(
new List(),
Segment2DLoopCollectionHelper.CreateFromString(
string.Join(Environment.NewLine,
"10",
"...",
"1.2",
"...",
"...",
"...",
"4.3",
"...",
"...",
"...",
"...")))
}, Enumerable.Empty())
{
IntersectionX = 1.0
};
// Call
PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile);
// Assert
Assert.AreEqual(profileName, transformed.Name);
Assert.AreEqual(SoilProfileType.SoilProfile2D, transformed.SoilProfileSourceType);
Assert.AreEqual(3, transformed.Layers.Count());
CollectionAssert.AreEquivalent(new[]
{
2.0,
4.0,
8.0
}, transformed.Layers.Select(rl => rl.Top));
Assert.AreEqual(1.0, transformed.Bottom);
}
[Test]
public void Transform_SoilProfile2DWithLayerFilledWithOtherLayer_ReturnsProfileWithBottomAndLayers()
{
// Setup
const string profileName = "SomeProfile";
const long pipingSoilProfileId = 1234L;
List loopHole = Segment2DLoopCollectionHelper.CreateFromString(
string.Join(Environment.NewLine,
"5",
".....",
".4.1.",
".3.2.",
".....",
"....."));
SoilLayer2D soilLayer2D = SoilLayer2DTestFactory.CreateSoilLayer2D(
new[]
{
loopHole
},
Segment2DLoopCollectionHelper.CreateFromString(
string.Join(Environment.NewLine,
"5",
"2...3",
".....",
".....",
".....",
"1...4")));
soilLayer2D.NestedLayers = new[]
{
SoilLayer2DTestFactory.CreateSoilLayer2D(new IEnumerable[0], loopHole)
};
var profile = new SoilProfile2D(pipingSoilProfileId, profileName,
new List
{
soilLayer2D,
SoilLayer2DTestFactory.CreateSoilLayer2D(
new List(),
loopHole)
}, Enumerable.Empty())
{
IntersectionX = 2.0
};
// Call
PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile);
// Assert
Assert.AreEqual(profileName, transformed.Name);
Assert.AreEqual(SoilProfileType.SoilProfile2D, transformed.SoilProfileSourceType);
Assert.AreEqual(4, transformed.Layers.Count());
CollectionAssert.AreEquivalent(new[]
{
4.0,
3.0,
3.0,
2.0
}, transformed.Layers.Select(rl => rl.Top));
Assert.AreEqual(2.0, transformed.Bottom);
}
[Test]
public void Transform_InvalidSoilProfile1D_ThrowsImportedDataTransformException()
{
// Setup
const string profileName = "SomeProfile";
var random = new Random(22);
double bottom = random.NextDouble();
const long pipingSoilProfileId = 1234L;
var profile = new SoilProfile1D(pipingSoilProfileId,
profileName,
bottom,
Enumerable.Empty());
// Call
TestDelegate call = () => PipingSoilProfileTransformer.Transform(profile);
// Assert
var exception = Assert.Throws(call);
Exception innerException = exception.InnerException;
Assert.IsInstanceOf(innerException);
Assert.AreEqual(innerException.Message, exception.Message);
}
[Test]
public void Transform_SoilProfile1DWithSingleLayer_ReturnsProfileWithBottomAndALayer()
{
// Setup
const string profileName = "SomeProfile";
var random = new Random(22);
double bottom = random.NextDouble();
double top = random.NextDouble();
const long pipingSoilProfileId = 1234L;
var profile = new SoilProfile1D(pipingSoilProfileId,
profileName,
bottom,
new[]
{
SoilLayer1DTestFactory.CreateSoilLayer1DWithValidAquifer(top)
}
);
// Call
PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile);
// Assert
Assert.AreEqual(profileName, transformed.Name);
Assert.AreEqual(SoilProfileType.SoilProfile1D, transformed.SoilProfileSourceType);
PipingSoilLayer[] layers = transformed.Layers.ToArray();
Assert.AreEqual(1, layers.Length);
Assert.AreEqual(top, layers[0].Top);
Assert.AreEqual(bottom, transformed.Bottom);
}
[Test]
public void Transform_SoilProfile1DWithMultipleLayers_ReturnsProfileWithBottomAndALayer()
{
// Setup
const string profileName = "SomeProfile";
var random = new Random(22);
double bottom = random.NextDouble();
double top = bottom + random.NextDouble();
double top2 = bottom + random.NextDouble();
const long pipingSoilProfileId = 1234L;
var profile = new SoilProfile1D(pipingSoilProfileId,
profileName,
bottom,
new[]
{
SoilLayer1DTestFactory.CreateSoilLayer1DWithValidAquifer(top),
SoilLayer1DTestFactory.CreateSoilLayer1DWithValidAquifer(top2)
}
);
// Call
PipingSoilProfile transformed = PipingSoilProfileTransformer.Transform(profile);
// Assert
Assert.AreEqual(profileName, transformed.Name);
Assert.AreEqual(2, transformed.Layers.Count());
Assert.AreEqual(bottom, transformed.Bottom);
}
private static void AssertPipingSoilLayers(IEnumerable expectedSoilLayer2Ds,
IEnumerable actualSoilLayer2Ds)
{
PipingSoilLayer[] expectedSoilLayer2DsArray = expectedSoilLayer2Ds.ToArray();
PipingSoilLayer[] actualSoilLayers2DArray = actualSoilLayer2Ds.ToArray();
Assert.AreEqual(expectedSoilLayer2DsArray.Length, actualSoilLayers2DArray.Length);
for (var i = 0; i < expectedSoilLayer2DsArray.Length; i++)
{
AssertPipingSoilLayer(expectedSoilLayer2DsArray[i], actualSoilLayers2DArray[i]);
}
}
private static void AssertPipingSoilLayer(PipingSoilLayer expected, PipingSoilLayer actual)
{
Assert.AreEqual(expected.Top, actual.Top);
Assert.AreEqual(expected.IsAquifer, actual.IsAquifer);
Assert.AreEqual(expected.BelowPhreaticLevelMean, actual.BelowPhreaticLevelMean);
Assert.AreEqual(expected.BelowPhreaticLevelDeviation, actual.BelowPhreaticLevelDeviation);
Assert.AreEqual(expected.BelowPhreaticLevelShift, actual.BelowPhreaticLevelShift);
Assert.AreEqual(expected.DiameterD70Mean, actual.DiameterD70Mean);
Assert.AreEqual(expected.DiameterD70CoefficientOfVariation, actual.DiameterD70CoefficientOfVariation);
Assert.AreEqual(expected.PermeabilityMean, actual.PermeabilityMean);
Assert.AreEqual(expected.PermeabilityCoefficientOfVariation, actual.PermeabilityCoefficientOfVariation);
Assert.AreEqual(expected.MaterialName, actual.MaterialName);
Assert.AreEqual(expected.Color, actual.Color);
}
private class TestSoilProfile : ISoilProfile
{
public string Name { get; }
}
}
}