// 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.Drawing;
using System.Linq;
using Core.Common.Base.IO;
using Core.Common.IO.Readers;
using Core.Common.Utils.Builders;
using NUnit.Framework;
using Rhino.Mocks;
using Ringtoets.Piping.IO.Builders;
using Ringtoets.Piping.IO.Exceptions;
using Ringtoets.Piping.IO.SoilProfile;
using Ringtoets.Piping.IO.SoilProfile.Schema;
using Ringtoets.Piping.IO.Test.TestHelpers;
using Ringtoets.Piping.Primitives;
namespace Ringtoets.Piping.IO.Test.SoilProfile
{
[TestFixture]
public class SoilProfile2DReaderTest
{
private MockRepository mocks;
private IRowBasedDatabaseReader reader;
private readonly byte[] someGeometry = StringGeometryHelper.GetByteArray("" +
"" +
"001.1101.1" +
"" +
"" +
"001.1101.1" +
"" +
"" +
"");
[SetUp]
public void SetUp()
{
mocks = new MockRepository();
reader = mocks.DynamicMock();
}
[Test]
public void ReadFrom_InvalidCriticalProperty_ThrowsCriticalFileReadException()
{
// Setup
const string path = "A";
const string name = "B";
reader.Expect(r => r.Path).Return(path);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return(name);
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Throw(new InvalidCastException());
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, "Kritieke fout opgetreden bij het uitlezen van waardes uit kolommen in de database.");
Assert.AreEqual(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidRequiredProperty_ThrowsPipingSoilProfileReadException()
{
// Setup
const string name = "A";
const string path = "B";
reader.Expect(r => r.Path).Return(path);
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return(name).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Throw(new InvalidCastException());
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, "Ondergrondschematisatie bevat geen geldige waarde in kolom 'IntersectionX'.");
Assert.AreEqual(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_DoubleNaNIntersectionX_ThrowsPipingSoilProfileReadException()
{
// Setup
const string name = "profile";
const string path = "A";
reader.Expect(r => r.Path).Return(path);
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return(name).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(double.NaN);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string errorMessage = $"Geen geldige X waarde gevonden om intersectie te maken uit 2D profiel '{name}'.";
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, errorMessage);
Assert.AreEqual(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_ZeroLayerCount_ThrowsPipingSoilProfileReadException()
{
// Setup
const string name = "profile";
const string path = "A";
reader.Expect(r => r.Path).Return(path);
SetExpectations(0, name, 0.0, 1.0, string.Empty, 0, new byte[0], null, null, null, null, null, null);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, "Geen lagen gevonden voor de ondergrondschematisatie.");
Assert.AreEqual(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_NullGeometry_ThrowsPipingSoilProfileReadException()
{
// Setup
const string name = "profile";
const string path = "A";
reader.Expect(r => r.Path).Return(path);
SetExpectations(1, name, 0.0, 1.0, string.Empty, 0, null, null, null, null, null, null, null);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, "De geometrie is leeg.");
StringAssert.StartsWith(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_EmptyGeometry_ThrowsPipingSoilProfileReadException()
{
// Setup
const string name = "cool name";
const string path = "A";
SetExpectations(1, name, 0.0, 1.0, string.Empty, 0, new byte[0], null, null, null, null, null, null);
reader.Expect(r => r.Path).Return(path);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, "Het XML-document dat de geometrie beschrijft voor de laag is niet geldig.");
Assert.AreEqual(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidIsAquifer_ReturnsProfileWithNullValuesOnLayer()
{
// Setup
const string name = "cool name";
const string path = "A";
reader.Expect(r => r.Path).Return(path);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return(name);
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.IsAquifer)).Throw(new InvalidCastException());
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
var exception = Assert.Throws(test);
string expectedMessage = GetExpectedSoilProfileReaderErrorMessage(path, name, "Ondergrondschematisatie bevat geen geldige waarde in kolom 'IsAquifer'.");
Assert.AreEqual(expectedMessage, exception.Message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_NullValuesForLayer_ReturnsProfileWithNullValuesAndDefaultsOnLayer()
{
// Setup
SetExpectations(1, "", 0.0, null, null, null, someGeometry, null, null, null, null, null, null);
mocks.ReplayAll();
// Call
PipingSoilProfile profile = SoilProfile2DReader.ReadFrom(reader);
// Assert
Assert.AreEqual(1, profile.Layers.Count());
Assert.AreEqual(1.1, profile.Bottom);
PipingSoilLayer pipingSoilLayer = profile.Layers.First();
Assert.AreEqual(1.1, pipingSoilLayer.Top);
Assert.IsFalse(pipingSoilLayer.IsAquifer);
Assert.IsEmpty(pipingSoilLayer.MaterialName);
Assert.AreEqual(Color.Empty, pipingSoilLayer.Color);
Assert.IsNaN(pipingSoilLayer.BelowPhreaticLevelMean);
Assert.IsNaN(pipingSoilLayer.BelowPhreaticLevelDeviation);
Assert.IsNaN(pipingSoilLayer.DiameterD70Mean);
Assert.IsNaN(pipingSoilLayer.DiameterD70CoefficientOfVariation);
Assert.IsNaN(pipingSoilLayer.PermeabilityMean);
Assert.IsNaN(pipingSoilLayer.PermeabilityCoefficientOfVariation);
mocks.VerifyAll();
}
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(3)]
public void ReadFrom_ProperValuesForNumberOfLayers_ReturnsProfileWithNumberOfLayers(int layerCount)
{
// Setup
var random = new Random(22);
const double intersectionX = 0.5;
const string materialName = "material";
Color color = Color.FromArgb(Color.AliceBlue.ToArgb());
double belowPhreaticLevelMean = random.NextDouble();
double belowPhreaticLevelDeviation = random.NextDouble();
double diameterD70Mean = random.NextDouble();
double diameterD70CoefficientOfVariation = random.NextDouble();
double permeabilityMean = random.NextDouble();
double permeabilityCoefficientOfVariation = random.NextDouble();
SetExpectations(
layerCount,
"",
intersectionX,
1.0,
materialName,
color.ToArgb(),
someGeometry,
belowPhreaticLevelMean,
belowPhreaticLevelDeviation,
diameterD70Mean,
diameterD70CoefficientOfVariation,
permeabilityMean,
permeabilityCoefficientOfVariation);
mocks.ReplayAll();
// Call
PipingSoilProfile profile = SoilProfile2DReader.ReadFrom(reader);
// Assert
Assert.AreEqual(layerCount, profile.Layers.Count());
Assert.AreEqual(1.1, profile.Bottom);
PipingSoilLayer pipingSoilLayer = profile.Layers.First();
Assert.AreEqual(1.1, pipingSoilLayer.Top);
Assert.IsTrue(pipingSoilLayer.IsAquifer);
Assert.AreEqual(materialName, pipingSoilLayer.MaterialName);
Assert.AreEqual(color, pipingSoilLayer.Color);
Assert.AreEqual(belowPhreaticLevelMean, pipingSoilLayer.BelowPhreaticLevelMean);
Assert.AreEqual(belowPhreaticLevelDeviation, pipingSoilLayer.BelowPhreaticLevelDeviation);
Assert.AreEqual(diameterD70Mean, pipingSoilLayer.DiameterD70Mean);
Assert.AreEqual(diameterD70CoefficientOfVariation, pipingSoilLayer.DiameterD70CoefficientOfVariation);
Assert.AreEqual(permeabilityMean, pipingSoilLayer.PermeabilityMean);
Assert.AreEqual(permeabilityCoefficientOfVariation, pipingSoilLayer.PermeabilityCoefficientOfVariation);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidBelowPhreaticLevelDistributionValue_ThrowsPipingSoilProfileReadException()
{
// Setup
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return("");
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(0.0).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerGeometry)).Return(someGeometry).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.BelowPhreaticLevelDistribution)).Return(1);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
string message = Assert.Throws(test).Message;
string expected = string.Format(
"Fout bij het lezen van bestand '' (ondergrondschematisatie ''): parameter '{0}' is niet verschoven lognormaal verdeeld.",
"Verzadigd gewicht");
Assert.AreEqual(expected, message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidDiameterD70DistributionValue_ThrowsPipingSoilProfileReadException()
{
// Setup
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return("");
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(0.0).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerGeometry)).Return(someGeometry).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70Distribution)).Return(1);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
string message = Assert.Throws(test).Message;
string expected = string.Format(
"Fout bij het lezen van bestand '' (ondergrondschematisatie ''): parameter '{0}' is niet lognormaal verdeeld.",
"Korrelgrootte");
Assert.AreEqual(expected, message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidDiameterD70ShiftValue_ThrowsPipingSoilProfileReadException()
{
// Setup
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return("");
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(0.0).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerGeometry)).Return(someGeometry).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70Distribution)).Return(SoilLayerConstants.LogNormalDistributionValue);
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70Shift)).Return(1);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
string message = Assert.Throws(test).Message;
string expected = string.Format(
"Fout bij het lezen van bestand '' (ondergrondschematisatie ''): parameter '{0}' is niet lognormaal verdeeld.",
"Korrelgrootte");
Assert.AreEqual(expected, message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidPermeabilityDistributionValue_ThrowsPipingSoilProfileReadException()
{
// Setup
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return("");
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(0.0).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerGeometry)).Return(someGeometry).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityDistribution)).Return(1);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
string message = Assert.Throws(test).Message;
string expected = string.Format(
"Fout bij het lezen van bestand '' (ondergrondschematisatie ''): parameter '{0}' is niet lognormaal verdeeld.",
"Doorlatendheid");
Assert.AreEqual(expected, message);
mocks.VerifyAll();
}
[Test]
public void ReadFrom_InvalidPermeabilityShiftValue_ThrowsPipingSoilProfileReadException()
{
// Setup
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(1);
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return("");
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(0.0).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerGeometry)).Return(someGeometry).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityDistribution)).Return(SoilLayerConstants.LogNormalDistributionValue);
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityShift)).Return(1);
mocks.ReplayAll();
// Call
TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader);
// Assert
string message = Assert.Throws(test).Message;
string expected = string.Format(
"Fout bij het lezen van bestand '' (ondergrondschematisatie ''): parameter '{0}' is niet lognormaal verdeeld.",
"Doorlatendheid");
Assert.AreEqual(expected, message);
mocks.VerifyAll();
}
private void SetExpectations(int layerCount, string profileName, double intersectionX, double? isAquifer,
string materialName, double? color, byte[] geometry, double? belowPhreaticLevelMean,
double? belowPhreaticLevelDeviation, double? diameterD70Mean, double? diameterD70CoefficientOfVariation,
double? permeabilityMean, double? permeabilityCoefficientOfVariation)
{
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerCount)).Return(layerCount).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.ProfileName)).Return(profileName).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.IntersectionX)).Return(intersectionX).Repeat.Any();
reader.Expect(r => r.Read(SoilProfileTableColumns.LayerGeometry)).Return(geometry).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.IsAquifer)).Return(isAquifer).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.MaterialName)).Return(materialName).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.Color)).Return(color).Repeat.Any();
const int logNormalDistribution = 3;
const int logNormalShift = 0;
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.BelowPhreaticLevelDistribution)).Return(logNormalDistribution).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.BelowPhreaticLevelShift)).Return(logNormalShift).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.BelowPhreaticLevelMean)).Return(belowPhreaticLevelMean).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.BelowPhreaticLevelDeviation)).Return(belowPhreaticLevelDeviation).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70Distribution)).Return(logNormalDistribution).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70Shift)).Return(logNormalShift).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70Mean)).Return(diameterD70Mean).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.DiameterD70CoefficientOfVariation)).Return(diameterD70CoefficientOfVariation).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityDistribution)).Return(logNormalDistribution).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityShift)).Return(logNormalShift).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityMean)).Return(permeabilityMean).Repeat.Any();
reader.Expect(r => r.ReadOrDefault(SoilProfileTableColumns.PermeabilityCoefficientOfVariation)).Return(permeabilityCoefficientOfVariation).Repeat.Any();
}
private static string GetExpectedSoilProfileReaderErrorMessage(string path, string name, string errorMessage)
{
return new FileReaderErrorMessageBuilder(path)
.WithSubject($"ondergrondschematisatie '{name}'")
.Build(errorMessage);
}
}
}