// 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;
using Core.Common.Base.Geometry;
using Core.Common.TestUtil;
using NUnit.Framework;
using Ringtoets.MacroStabilityInwards.Data.SoilProfile;
using Ringtoets.MacroStabilityInwards.Data.TestUtil.SoilProfile;
using Ringtoets.MacroStabilityInwards.Primitives;
namespace Ringtoets.MacroStabilityInwards.Data.Test.SoilProfile
{
[TestFixture]
public class MacroStabilityInwardsStochasticSoilModelTest
{
[Test]
public void Constructor_WithoutName_ExpectedValues()
{
// Setup
var random = new Random(21);
// Call
TestDelegate test = () => new MacroStabilityInwardsStochasticSoilModel(null, new[]
{
new Point2D(random.NextDouble(), random.NextDouble())
},
new[]
{
CreateStochasticSoilProfile()
});
// Assert
var exception = Assert.Throws(test);
Assert.AreEqual("name", exception.ParamName);
}
[Test]
public void Constructor_GeometryNull_ThrowsArgumentNullException()
{
// Call
TestDelegate call = () => new MacroStabilityInwardsStochasticSoilModel(string.Empty, null, new[]
{
CreateStochasticSoilProfile()
});
// Assert
var exception = Assert.Throws(call);
Assert.AreEqual("geometry", exception.ParamName);
}
[Test]
public void Constructor_GeometryEmpty_ThrowsArgumentException()
{
// Setup
const string name = "modelName";
// Call
TestDelegate call = () => new MacroStabilityInwardsStochasticSoilModel(name, Enumerable.Empty(), new[]
{
CreateStochasticSoilProfile()
});
// Assert
string expectedMessage = $"Het stochastische ondergrondmodel '{name}' moet een geometrie bevatten.";
TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage);
}
[Test]
public void Constructor_StochasticSoilProfilesNull_ThrowsArgumentNullException()
{
// Setup
var random = new Random(21);
const string name = "name";
var geometry = new[]
{
new Point2D(random.NextDouble(), random.NextDouble())
};
// Call
TestDelegate call = () => new MacroStabilityInwardsStochasticSoilModel(name, geometry, null);
// Assert
var exception = Assert.Throws(call);
Assert.AreEqual("stochasticSoilProfiles", exception.ParamName);
}
[Test]
public void Constructor_StochasticSoilProfilesEmpty_ThrowsArgumentException()
{
// Setup
var random = new Random(21);
const string name = "name";
var geometry = new[]
{
new Point2D(random.NextDouble(), random.NextDouble())
};
// Call
TestDelegate call = () => new MacroStabilityInwardsStochasticSoilModel(name,
geometry,
Enumerable.Empty());
// Assert
string expectedMessage = $"Er zijn geen ondergrondschematisaties gevonden in het stochastische ondergrondmodel '{name}'.";
TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage);
}
[Test]
[TestCase("")]
[TestCase("segmentSoilModelName")]
public void Constructor_WithValidParameters_ExpectedValues(string segmentSoilModelName)
{
// Setup
var random = new Random(21);
var geometry = new[]
{
new Point2D(random.NextDouble(), random.NextDouble())
};
IEnumerable stochasticSoilProfiles = new[]
{
CreateStochasticSoilProfile()
};
// Call
var stochasticSoilModel = new MacroStabilityInwardsStochasticSoilModel(segmentSoilModelName, geometry, stochasticSoilProfiles);
// Assert
Assert.IsInstanceOf(stochasticSoilModel);
Assert.AreEqual(segmentSoilModelName, stochasticSoilModel.Name);
Assert.AreSame(geometry, stochasticSoilModel.Geometry);
CollectionAssert.AreEqual(stochasticSoilProfiles, stochasticSoilModel.StochasticSoilProfiles);
}
[Test]
public void Update_WithNullModel_ThrowsArgumentNullException()
{
// Setup
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
CreateStochasticSoilProfile()
});
// Call
TestDelegate test = () => model.Update(null);
// Assert
string paramName = Assert.Throws(test).ParamName;
Assert.AreEqual("fromModel", paramName);
}
[Test]
public void Update_ModelWithUpdatedProperties_PropertiesUpdated()
{
// Setup
var model = new MacroStabilityInwardsStochasticSoilModel("name", new[]
{
new Point2D(1, 2),
new Point2D(4, 5)
}, new[]
{
CreateStochasticSoilProfile()
});
const string expectedName = "otherName";
var otherModel = new MacroStabilityInwardsStochasticSoilModel(expectedName, new[]
{
new Point2D(4, 2)
}, new[]
{
CreateStochasticSoilProfile()
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
AssertStochasticSoilModelAreEqual(otherModel, model);
CollectionAssert.IsEmpty(difference.AddedProfiles);
CollectionAssert.IsEmpty(difference.UpdatedProfiles);
CollectionAssert.IsEmpty(difference.RemovedProfiles);
}
[Test]
public void Update_ModelWithAddedProfile_ProfileAdded()
{
// Setup
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
CreateStochasticSoilProfile()
});
var expectedAddedProfile = new MacroStabilityInwardsStochasticSoilProfile(0.2, new TestSoilProfile("Added Profile"));
MacroStabilityInwardsStochasticSoilModel otherModel = CreateValidModel(new[]
{
CreateStochasticSoilProfile(),
expectedAddedProfile
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
AssertStochasticSoilModelAreEqual(otherModel, model);
CollectionAssert.AreEqual(new[]
{
expectedAddedProfile
}, difference.AddedProfiles);
CollectionAssert.IsEmpty(difference.UpdatedProfiles);
CollectionAssert.IsEmpty(difference.RemovedProfiles);
}
[Test]
public void Update_ModelWithUpdatedProfile_ProfileUpdated()
{
// Setup
const string profileName = "A";
var expectedUpdatedProfile = new MacroStabilityInwardsStochasticSoilProfile(
0.2, new MacroStabilityInwardsSoilProfile1D(profileName, -2, CreateLayers1D()));
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
expectedUpdatedProfile
});
MacroStabilityInwardsStochasticSoilModel otherModel = CreateValidModel(new[]
{
new MacroStabilityInwardsStochasticSoilProfile(
0.2, new MacroStabilityInwardsSoilProfile1D(profileName, -1, CreateLayers1D()))
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
AssertStochasticSoilModelAreEqual(otherModel, model);
Assert.AreEqual(expectedUpdatedProfile, otherModel.StochasticSoilProfiles.ElementAt(0));
CollectionAssert.IsEmpty(difference.AddedProfiles);
CollectionAssert.AreEqual(new[]
{
expectedUpdatedProfile
}, difference.UpdatedProfiles);
CollectionAssert.IsEmpty(difference.RemovedProfiles);
}
[Test]
public void Update_ModelWithUpdatedStochasticSoilProfile_ProfileUpdated()
{
// Setup
const string profileName = "A";
var soilProfile = new MacroStabilityInwardsSoilProfile1D(profileName, -2, CreateLayers1D());
var expectedUpdatedProfile = new MacroStabilityInwardsStochasticSoilProfile(0.2, soilProfile);
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
expectedUpdatedProfile
});
MacroStabilityInwardsStochasticSoilModel otherModel = CreateValidModel(new[]
{
new MacroStabilityInwardsStochasticSoilProfile(0.5, soilProfile)
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
CollectionAssert.IsEmpty(difference.AddedProfiles);
CollectionAssert.AreEqual(new[]
{
expectedUpdatedProfile
}, difference.UpdatedProfiles);
CollectionAssert.IsEmpty(difference.RemovedProfiles);
}
[Test]
public void Update_ModelWithRemovedProfile_ProfileRemoved()
{
// Setup
const string profileName = "A";
var soilProfile = new MacroStabilityInwardsSoilProfile1D(profileName, -2, CreateLayers1D());
var expectedRemovedProfile = new MacroStabilityInwardsStochasticSoilProfile(0.2, soilProfile);
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
CreateStochasticSoilProfile(),
expectedRemovedProfile
});
MacroStabilityInwardsStochasticSoilModel otherModel = CreateValidModel(new[]
{
CreateStochasticSoilProfile()
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
CollectionAssert.IsEmpty(difference.AddedProfiles);
CollectionAssert.IsEmpty(difference.UpdatedProfiles);
CollectionAssert.AreEqual(new[]
{
expectedRemovedProfile
}, difference.RemovedProfiles);
}
[Test]
public void Update_ModelWithRemovedProfileSameNameOtherType_ProfileRemoved()
{
// Setup
const string profileName = "A";
var soilProfile = new MacroStabilityInwardsSoilProfile1D(profileName, -2, CreateLayers1D());
var expectedRemovedProfile = new MacroStabilityInwardsStochasticSoilProfile(0.2, soilProfile);
var newProfile = new MacroStabilityInwardsStochasticSoilProfile(
0.2,
new MacroStabilityInwardsSoilProfile2D(profileName, CreateLayers2D(), Enumerable.Empty()));
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
expectedRemovedProfile
});
MacroStabilityInwardsStochasticSoilModel otherModel = CreateValidModel(new[]
{
newProfile
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
CollectionAssert.AreEqual(new[]
{
newProfile
}, difference.AddedProfiles);
CollectionAssert.IsEmpty(difference.UpdatedProfiles);
CollectionAssert.AreEqual(new[]
{
expectedRemovedProfile
}, difference.RemovedProfiles);
}
[Test]
public void Update_WithOtherModel_PropertiesUpdated()
{
// Setup
const string equalProfileName = "nameA";
var stochasticProfileA = new MacroStabilityInwardsStochasticSoilProfile(0.5, CreateMacroStabilityInwardsSoilProfile(equalProfileName));
var stochasticProfileB = new MacroStabilityInwardsStochasticSoilProfile(0.5, CreateMacroStabilityInwardsSoilProfile("nameB"));
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
stochasticProfileA,
stochasticProfileB
});
const string otherName = "other name";
var otherGeometry = new[]
{
new Point2D(2, 0),
new Point2D(3, 0)
};
var otherStochasticProfileA = new MacroStabilityInwardsStochasticSoilProfile(0.7, new TestSoilProfile(equalProfileName));
var otherStochasticProfileB = new MacroStabilityInwardsStochasticSoilProfile(0.3, CreateMacroStabilityInwardsSoilProfile("other profile name"));
var otherModel = new MacroStabilityInwardsStochasticSoilModel(otherName, otherGeometry, new[]
{
otherStochasticProfileA,
otherStochasticProfileB
});
// Call
MacroStabilityInwardsStochasticSoilModelProfileDifference difference = model.Update(otherModel);
// Assert
AssertStochasticSoilModelAreEqual(otherModel, model);
Assert.AreSame(otherGeometry, model.Geometry);
MacroStabilityInwardsStochasticSoilProfile[] stochasticSoilProfiles = model.StochasticSoilProfiles.ToArray();
Assert.AreEqual(2, stochasticSoilProfiles.Length);
Assert.AreSame(stochasticProfileA, stochasticSoilProfiles[0]);
Assert.AreSame(otherStochasticProfileA.SoilProfile, stochasticSoilProfiles[0].SoilProfile);
Assert.AreNotSame(stochasticProfileB, stochasticSoilProfiles[1]);
Assert.AreSame(otherStochasticProfileB.SoilProfile, stochasticSoilProfiles[1].SoilProfile);
CollectionAssert.AreEqual(new[]
{
stochasticProfileA
}, difference.UpdatedProfiles);
CollectionAssert.AreEqual(new[]
{
stochasticProfileB
}, difference.RemovedProfiles);
CollectionAssert.AreEqual(new[]
{
otherStochasticProfileB
}, difference.AddedProfiles);
}
[Test]
public void Update_ModelsWithAddedProfilesWithSameNames_ThrowsInvalidOperationException()
{
// Setup
const string profileName = "Name of Profile";
MacroStabilityInwardsSoilProfile1D soilProfileOne =
MacroStabilityInwardsSoilProfile1DTestFactory.CreateMacroStabilityInwardsSoilProfile1D(profileName);
var addedStochasticSoilProfile = new MacroStabilityInwardsStochasticSoilProfile(0.2, soilProfileOne);
MacroStabilityInwardsStochasticSoilModel otherModel = CreateValidModel(new[]
{
addedStochasticSoilProfile
});
MacroStabilityInwardsSoilProfile1D soilProfile = MacroStabilityInwardsSoilProfile1DTestFactory.CreateMacroStabilityInwardsSoilProfile1D(profileName);
var existingStochasticSoilProfileOne = new MacroStabilityInwardsStochasticSoilProfile(0.2, soilProfile);
var existingStochasticSoilProfileTwo = new MacroStabilityInwardsStochasticSoilProfile(0.3, soilProfile);
MacroStabilityInwardsStochasticSoilModel model = CreateValidModel(new[]
{
existingStochasticSoilProfileOne,
existingStochasticSoilProfileTwo
});
// Call
TestDelegate call = () => model.Update(otherModel);
// Assert
Assert.Throws(call);
Assert.AreEqual(1, otherModel.StochasticSoilProfiles.Count());
Assert.AreEqual(addedStochasticSoilProfile, otherModel.StochasticSoilProfiles.First());
Assert.AreEqual(2, model.StochasticSoilProfiles.Count());
CollectionAssert.AreEqual(new[]
{
existingStochasticSoilProfileOne,
existingStochasticSoilProfileTwo
}, model.StochasticSoilProfiles);
}
[Test]
[TestCase("")]
[TestCase("some name")]
public void ToString_WithName_ReturnsName(string name)
{
// Setup
var random = new Random(21);
var stochasticSoilModel = new MacroStabilityInwardsStochasticSoilModel(name,
new[]
{
new Point2D(random.NextDouble(), random.NextDouble())
},
new[]
{
new MacroStabilityInwardsStochasticSoilProfile(random.NextDouble(), new TestSoilProfile())
});
// Call & Assert
Assert.AreEqual(name, stochasticSoilModel.ToString());
}
private static IMacroStabilityInwardsSoilProfile CreateMacroStabilityInwardsSoilProfile(string name)
{
return new TestSoilProfile(name);
}
private class TestSoilProfile : IMacroStabilityInwardsSoilProfile
{
public TestSoilProfile() {}
public TestSoilProfile(string name)
{
Name = name;
}
public string Name { get; } = "";
public IEnumerable Layers { get; }
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
if (obj.GetType() != GetType())
{
return false;
}
return Equals((TestSoilProfile) obj);
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
private bool Equals(TestSoilProfile other)
{
return string.Equals(Name, other.Name);
}
}
private static IEnumerable CreateLayers1D()
{
return new[]
{
new MacroStabilityInwardsSoilLayer1D(2)
};
}
private static IEnumerable CreateLayers2D()
{
var outerRing = new Ring(new[]
{
new Point2D(3, 2),
new Point2D(3, 5)
});
return new[]
{
new MacroStabilityInwardsSoilLayer2D(outerRing, Enumerable.Empty())
};
}
private static MacroStabilityInwardsStochasticSoilModel CreateValidModel(IEnumerable stochasticSoilProfiles)
{
var random = new Random(21);
return new MacroStabilityInwardsStochasticSoilModel("name",
new[]
{
new Point2D(random.NextDouble(), random.NextDouble())
}, stochasticSoilProfiles);
}
private static MacroStabilityInwardsStochasticSoilProfile CreateStochasticSoilProfile()
{
var random = new Random(21);
return new MacroStabilityInwardsStochasticSoilProfile(random.NextDouble(), new TestSoilProfile());
}
private static void AssertStochasticSoilModelAreEqual(MacroStabilityInwardsStochasticSoilModel expected,
MacroStabilityInwardsStochasticSoilModel actual)
{
Assert.AreEqual(expected.Name, actual.Name);
CollectionAssert.AreEqual(expected.Geometry, actual.Geometry);
CollectionAssert.AreEqual(expected.StochasticSoilProfiles, actual.StochasticSoilProfiles);
}
}
}