Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs =================================================================== diff -u -r1f74cee51a8e169fc4efac01df521aa8755c438a -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1f74cee51a8e169fc4efac01df521aa8755c438a) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -286,5 +286,23 @@ return ResourceManager.GetString("SoilLayer2DReader_Geometry_contains_no_valid_xml", resourceCulture); } } + + /// + /// Looks up a localized string similar to De geometrie is leeg.. + /// + public static string SoilLayer2DReader_Geometry_is_null { + get { + return ResourceManager.GetString("SoilLayer2DReader_Geometry_is_null", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Kon het XML-schema bestand niet laden om te kijken of de geometrie van de ondergrondlaag valide is.. + /// + public static string SoilLayer2DReader_Schema_file_could_not_be_loaded { + get { + return ResourceManager.GetString("SoilLayer2DReader_Schema_file_could_not_be_loaded", resourceCulture); + } + } } } Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx =================================================================== diff -u -r1f74cee51a8e169fc4efac01df521aa8755c438a -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 1f74cee51a8e169fc4efac01df521aa8755c438a) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -192,4 +192,10 @@ Het XML-document dat de geometrie beschrijft voor de laag is niet geldig. + + De geometrie is leeg. + + + Kon het XML-schema bestand niet laden om te kijken of de geometrie van de ondergrondlaag valide is. + \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj =================================================================== diff -u -rd2b5b334c49948fa49297a1d24c13bc98aa6ee1e -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj (.../Ringtoets.Piping.IO.csproj) (revision d2b5b334c49948fa49297a1d24c13bc98aa6ee1e) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj (.../Ringtoets.Piping.IO.csproj) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -109,9 +109,13 @@ C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.XML.dll + + + Designer + Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilLayer2DReader.cs =================================================================== diff -u -rd2b5b334c49948fa49297a1d24c13bc98aa6ee1e -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilLayer2DReader.cs (.../SoilLayer2DReader.cs) (revision d2b5b334c49948fa49297a1d24c13bc98aa6ee1e) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilLayer2DReader.cs (.../SoilLayer2DReader.cs) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -1,8 +1,12 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Xml; +using System.Xml.Linq; +using System.Xml.Schema; +using System.Xml.XPath; using Ringtoets.Piping.Data; using Ringtoets.Piping.IO.Builders; using Ringtoets.Piping.IO.Properties; @@ -23,212 +27,171 @@ private const string xElementName = "X"; private const string zElementName = "Z"; - private readonly XmlTextReader xmlTextReader; + private readonly XmlSchemaSet schema; /// - /// Constructs a new , which uses the as the source of the + /// Constructs an instance of . + /// + /// Thrown when the XML-schema + /// could not be loaded. + internal SoilLayer2DReader() + { + schema = LoadXmlSchema(); + } + + /// + /// Reads a new using the as the source of the /// geometry for a . /// - /// An array of which contains the information of a - /// in an XML document. - /// Thrown when is null. - internal SoilLayer2DReader(byte[] geometry) + /// An of which contains the information + /// of a in an XML document. + /// A new with information taken from the XML document. + /// Thrown when is null. + /// Thrown when: + /// + /// is not valid XML. + /// does not validate to the schema. + /// + /// + internal SoilLayer2D Read(byte[] geometry) { + if (geometry == null) + { + throw new ArgumentNullException("geometry", Resources.SoilLayer2DReader_Geometry_is_null); + } try { - xmlTextReader = new XmlTextReader(new MemoryStream(geometry)); + return Read(XDocument.Load(new MemoryStream(geometry))); } - catch (ArgumentNullException e) + catch (XmlException e) { throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e); } } /// - /// Reads the XML document and from this obtains the required information and constructs a based - /// on this information. + /// Reads a new using the as the source of the + /// geometry for a . /// + /// An which contains the information of a + /// in an XML document. /// A new with information taken from the XML document. + /// Thrown when is null. /// Thrown when: /// - /// Reading from the XML document of the failed. - /// The segments do not form a loop for either the inner or outer loop. + /// is not valid XML. + /// does not validate to the schema. /// /// - internal SoilLayer2D Read() + internal SoilLayer2D Read(XDocument geometry) { + ValidateToSchema(geometry); + + return ParseLayer(geometry); + } + + private SoilLayer2D ParseLayer(XDocument geometry) + { var pipingSoilLayer = new SoilLayer2D(); - try + var xmlOuterLoop = geometry.XPathSelectElement(string.Format("//{0}", outerLoopElementName)); + var xmlInnerLoops = geometry.XPathSelectElements(string.Format("//{0}", innerLoopElementName)); + + if (xmlOuterLoop != null) { - while (xmlTextReader.Read()) - { - List outerLoop; - List innerLoop; - if (TryParseLoop(outerLoopElementName, out outerLoop)) - { - pipingSoilLayer.OuterLoop = outerLoop; - } - if (TryParseLoop(innerLoopElementName, out innerLoop)) - { - pipingSoilLayer.AddInnerLoop(innerLoop); - } - } + pipingSoilLayer.OuterLoop = ParseGeometryLoop(xmlOuterLoop); } - catch (XmlException e) + foreach (XElement loop in xmlInnerLoops) { - throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e); + pipingSoilLayer.AddInnerLoop(ParseGeometryLoop(loop)); } - catch (ArgumentException e) - { - throw new SoilLayer2DConversionException(e.Message, e); - } - return pipingSoilLayer; } /// - /// Tries to parse the element with the given , which the reader should be currently pointing at, as a loop. + /// Adds the validation schema for the geometry to the . /// - /// The name of the element which the reader should be currently pointing at. - /// The result of parsing the element as a loop. null if the current element's name does not match . - /// True if the reader currently points to an element with name . False otherwise. - /// Thrown when not both HeadPoint and EndPoint are defined in - /// the GeometryCurve XML element. - private bool TryParseLoop(string elementName, out List loop) + /// The to add the validation schema to. + /// Thrown when: + /// + /// The validation schema could not be correctly loaded. + /// The validation failed. + /// + /// + private void ValidateToSchema(XDocument document) { - loop = null; - - if (IsElementWithName(elementName)) + try { - loop = new List(); - - if (!IsEmptyElement()) - { - while (xmlTextReader.Read() && !IsEndElementWithName(elementName)) - { - Segment2D segment; - if (TryParseSegment(out segment)) - { - loop.Add(segment); - } - } - } - return true; + document.Validate(schema, null); } - return false; + catch (InvalidOperationException e) + { + throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e); + } + catch (XmlSchemaValidationException e) + { + throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e); + } } - /// - /// Tries to parse a GeometryCurve XML element to a . - /// - /// The segment reference in which to put the parsed . - /// true if a segment could be parsed. false otherwise. - /// Thrown when not both HeadPoint and EndPoint are defined in - /// the GeometryCurve XML element. - private bool TryParseSegment(out Segment2D segment) + private XmlSchemaSet LoadXmlSchema() { - segment = null; - if (IsElementWithName(geometryCurveElementName) || IsElementWithName(endPointElementName)) + var schemaFile = GetType().Assembly.GetManifestResourceStream("Ringtoets.Piping.IO.SoilProfile.XmlGeometrySchema.xsd"); + if (schemaFile == null) { - var points = new Point2D[2]; - var index = 0; - while (xmlTextReader.Read() && !IsEndElementWithName(geometryCurveElementName)) - { - Point2D point; - if (TryParsePoint(out point)) - { - points[index] = point; - index++; - } - } - try - { - segment = new Segment2D(points[0], points[1]); - return true; - } - catch (ArgumentNullException e) - { - throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, e); - } + throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Schema_file_could_not_be_loaded); } - return false; + try + { + var xmlSchema = new XmlSchemaSet(); + xmlSchema.Add(XmlSchema.Read(schemaFile, null)); + return xmlSchema; + } + catch (XmlSchemaException e) + { + throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Schema_file_could_not_be_loaded, e); + } } - /// - /// Finds out whether the element which the reader is currently pointing at is empty. - /// - /// True if the element is empty. False otherwise. - private bool IsEmptyElement() + private IEnumerable ParseGeometryLoop(XElement loop) { - return xmlTextReader.IsEmptyElement; + var loops = new Collection(); + var curves = loop.XPathSelectElements(string.Format("//{0}", geometryCurveElementName)); + + foreach (XElement curve in curves) + { + loops.Add(ParseGeometryCurve(curve)); + } + return loops; } - /// - /// Tries to parse the element which the reader is currently pointing at as a point. - /// - /// The result of parsing the element as a point. null if current element is not a head or end point. - /// True if the reader currently points to an element with name or . False otherwise. - private bool TryParsePoint(out Point2D point) + private Segment2D ParseGeometryCurve(XElement curve) { - point = null; - - if (IsElementWithName(headPointElementName) || IsElementWithName(endPointElementName)) + var headDefinition = curve.Element(headPointElementName); + var endDefinition = curve.Element(endPointElementName); + if (headDefinition != null && endDefinition != null) { - var pointValues = ReadChildValues(); - point = new Point2D - { - X = double.Parse(pointValues[xElementName], CultureInfo.InvariantCulture), - Y = double.Parse(pointValues[zElementName], CultureInfo.InvariantCulture) - }; - return true; + return new Segment2D( + ParsePoint(headDefinition), + ParsePoint(endDefinition) + ); } - return false; + throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml); } - /// - /// Reads the name and values for the children of the current element and puts them in a name indexed dictionary. - /// - /// A . For each entry, key is equal to child element name and value is equal to the value of the child element's text node. - private Dictionary ReadChildValues() + private Point2D ParsePoint(XElement point) { - string elementName = xmlTextReader.Name; - var nodeSibblings = new Dictionary(); - - while (xmlTextReader.Read() && !IsEndElementWithName(elementName)) + var x = point.Element(xElementName); + var y = point.Element(zElementName); + if (x != null && y != null) { - if (xmlTextReader.NodeType == XmlNodeType.Element) + return new Point2D { - nodeSibblings[xmlTextReader.Name] = xmlTextReader.ReadString(); - } + X = double.Parse(x.Value, CultureInfo.InvariantCulture), + Y = double.Parse(y.Value, CultureInfo.InvariantCulture) + }; } - - return nodeSibblings; + throw new SoilLayer2DConversionException(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml); } - - /// - /// Checks whether the element the reader is currently pointing at is of type and has a name equal to . - /// - /// The name which the element should have. - /// True if the current element has type and its name is equal to . - private bool IsElementWithName(string name) - { - var isElement = xmlTextReader.NodeType == XmlNodeType.Element; - var isPoint = xmlTextReader.Name == name; - - return isElement && isPoint; - } - /// - /// Checks whether the element the reader is currently pointing at is of type and has a name equal to . - /// - /// The name which the end element should have. - /// True if the current element has type and its name is equal to . - private bool IsEndElementWithName(string name) - { - var isElement = xmlTextReader.NodeType == XmlNodeType.EndElement; - var isPoint = xmlTextReader.Name == name; - - return isElement && isPoint; - } } } \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile2DReader.cs =================================================================== diff -u -rd2b5b334c49948fa49297a1d24c13bc98aa6ee1e -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile2DReader.cs (.../SoilProfile2DReader.cs) (revision d2b5b334c49948fa49297a1d24c13bc98aa6ee1e) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/SoilProfile2DReader.cs (.../SoilProfile2DReader.cs) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -1,5 +1,7 @@ using System; using System.Data.SQLite; +using System.IO; +using System.Xml; using Ringtoets.Piping.Data; using Ringtoets.Piping.IO.Builders; using Ringtoets.Piping.IO.Exceptions; @@ -64,7 +66,8 @@ /// Thrown when: /// /// A column for a layer property did not contain a value of the expected type. - /// Thrown when the read geometry does not contain segments that form form a loop for either the inner or outer loop. + /// The database contains an invalid XML definition for geometry. + /// The read geometry does not contain segments that form form a loop for either the inner or outer loop. /// private static SoilLayer2D ReadPiping2DSoilLayer(IRowBasedDatabaseReader reader, string profileName) { @@ -74,7 +77,7 @@ try { var geometryValue = ReadGeometryFrom(reader, profileName); - pipingSoilLayer = new SoilLayer2DReader(geometryValue).Read(); + pipingSoilLayer = new SoilLayer2DReader().Read(geometryValue); } catch (SoilLayer2DConversionException e) { Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/XmlGeometrySchema.xsd =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/XmlGeometrySchema.xsd (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/SoilProfile/XmlGeometrySchema.xsd (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj =================================================================== diff -u -r79b1cdcf9dcdbe4c015f5fc6b42605a00386b120 -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj (.../Ringtoets.Piping.IO.Test.csproj) (revision 79b1cdcf9dcdbe4c015f5fc6b42605a00386b120) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj (.../Ringtoets.Piping.IO.Test.csproj) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -54,6 +54,7 @@ + @@ -67,7 +68,7 @@ - + Fisheye: Tag 0047bcf51f94a295f3e4854f9b93594ad01a9e70 refers to a dead (removed) revision in file `Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/PipingSoilLayer2DReaderTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/SoilLayer2DReaderTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/SoilLayer2DReaderTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/SoilLayer2DReaderTest.cs (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using NUnit.Framework; +using Ringtoets.Piping.Data; +using Ringtoets.Piping.IO.Builders; +using Ringtoets.Piping.IO.Properties; +using Ringtoets.Piping.IO.SoilProfile; +using Ringtoets.Piping.IO.Test.TestHelpers; + +namespace Ringtoets.Piping.IO.Test.SoilProfile +{ + public class SoilLayer2DReaderTest + { + [Test] + public void Constructor_Always_ReturnsNewInstance() + { + // Call + var result = new SoilLayer2DReader(); + + // Assert + Assert.NotNull(result); + } + + [Test] + public void Read_MalformedXmlDocument_ThrowsSoilLayer2DConversionException() + { + // Setup + var xmlDoc = StringGeometryHelper.GetByteArray("test"); + var reader = new SoilLayer2DReader(); + + // Call + TestDelegate test = () => reader.Read(xmlDoc); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, exception.Message); + } + + [Test] + public void Read_XmlDocumentWithoutSaneContent_ThrowsSoilLayer2DConversionException() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument(""); + var reader = new SoilLayer2DReader(); + + // Call + TestDelegate test = () => reader.Read(xmlDoc); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual(Resources.SoilLayer2DReader_Geometry_contains_no_valid_xml, exception.Message); + } + + [Test] + public void Read_XmlDocumentWithEmptyOuterLoop_ReturnsLayerWithEmptyOuterLoop() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument(""); + var reader = new SoilLayer2DReader(); + + // Call + var result = reader.Read(xmlDoc); + + // Assert + Assert.NotNull(result); + CollectionAssert.IsEmpty(result.OuterLoop); + CollectionAssert.IsEmpty(result.InnerLoops); + } + + [Test] + public void Read_XmlDocumentWithEmptyInnerLoop_ReturnsLayerWithOneEmptyInnerLoop() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument(""); + var reader = new SoilLayer2DReader(); + + // Call + var result = reader.Read(xmlDoc); + + // Assert + Assert.NotNull(result); + Assert.IsNull(result.OuterLoop); + Assert.AreEqual(1, result.InnerLoops.Count()); + CollectionAssert.IsEmpty(result.InnerLoops.ElementAt(0)); + } + + [Test] + public void Read_XmlDocumentWithEmptyInnerLoopAndOuterLoop_ReturnsLayerWithEmptyInnerLoopAndEmptyOuterLoop() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument(""); + var reader = new SoilLayer2DReader(); + + // Call + var result = reader.Read(xmlDoc); + + // Assert + Assert.NotNull(result); + CollectionAssert.IsEmpty(result.OuterLoop); + Assert.AreEqual(1, result.InnerLoops.Count()); + CollectionAssert.IsEmpty(result.InnerLoops.ElementAt(0)); + } + + [Test] + [SetCulture("nl-NL")] + public void Read_NLXmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + { + Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint(); + } + + [Test] + [SetCulture("en-US")] + public void Read_ENXmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + { + Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint(); + } + + private void Read_XmlDocumentPointInOuterLoop_ReturnsLayerWithOuterLoopWithPoint() + { + // Setup + var random = new Random(22); + var invariantCulture = CultureInfo.InvariantCulture; + + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + + var x1String = x1.ToString(invariantCulture); + var x2String = x2.ToString(invariantCulture); + var y1String = y1.ToString(invariantCulture); + var y2String = y2.ToString(invariantCulture); + var parsedX1 = double.Parse(x1String, invariantCulture); + var parsedX2 = double.Parse(x2String, invariantCulture); + var parsedY1 = double.Parse(y1String, invariantCulture); + var parsedY2 = double.Parse(y2String, invariantCulture); + var sometempvarforbassie = string.Format(invariantCulture, "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "", + x1String, y1String, x2String, y2String); + var bytes = StringGeometryHelper.GetXmlDocument(sometempvarforbassie); + var xmlDoc = bytes; + var reader = new SoilLayer2DReader(); + + // Call + var result = reader.Read(xmlDoc); + + // Assert + Assert.NotNull(result); + Segment2D expectedSegment = new Segment2D(new Point2D(parsedX1, parsedY1), new Point2D(parsedX2, parsedY2)); + CollectionAssert.AreEqual(new List {expectedSegment, expectedSegment}, result.OuterLoop); + } + + [Test] + public void Read_XmlDocumentPointsInInnerLoop_ReturnsLayerWithInnerLoopWithSegment() + { + // Setup + var random = new Random(22); + var invariantCulture = CultureInfo.InvariantCulture; + + var x1 = random.NextDouble(); + var x2 = random.NextDouble(); + var y1 = random.NextDouble(); + var y2 = random.NextDouble(); + + var x1String = x1.ToString(invariantCulture); + var x2String = x2.ToString(invariantCulture); + var y1String = y1.ToString(invariantCulture); + var y2String = y2.ToString(invariantCulture); + var parsedX1 = double.Parse(x1String, invariantCulture); + var parsedX2 = double.Parse(x2String, invariantCulture); + var parsedY1 = double.Parse(y1String, invariantCulture); + var parsedY2 = double.Parse(y2String, invariantCulture); + var xmlDoc = StringGeometryHelper.GetXmlDocument(string.Format(invariantCulture, "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "" + + "{0}0.1{1}" + + "{2}0.1{3}" + + "", x1String, y1String, x2String, y2String)); + var reader = new SoilLayer2DReader(); + + // Call + var result = reader.Read(xmlDoc); + + // Assert + Assert.NotNull(result); + Segment2D expectedSegment = new Segment2D(new Point2D(parsedX1, parsedY1), new Point2D(parsedX2, parsedY2)); + var expectedCollection = new Collection> { new List { expectedSegment, expectedSegment } }; + CollectionAssert.AreEqual(expectedCollection, result.InnerLoops); + } + + [Test] + public void Read_XmlDocumentSinglePointOuterLoopGeometryCurve_ThrowsSoilLayer2DConversionException() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument("10.11.1"); + var reader = new SoilLayer2DReader(); + + // Call + TestDelegate test = () => { reader.Read(xmlDoc); }; + + // Assert + Assert.Throws(test); + } + + [Test] + public void Read_XmlDocumentSinglePointInnerLoopGeometryCurve_ThrowsSoilLayer2DConversionException() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument("00.11.1"); + var reader = new SoilLayer2DReader(); + + // Call + TestDelegate test = () => { reader.Read(xmlDoc); }; + + // Assert + Assert.Throws(test); + } + + [Test] + public void Read_XmlDocumentEqualSegments_ReturnsTwoEqualSegments() + { + // Setup + var xmlDoc = StringGeometryHelper.GetXmlDocument("" + + "" + + "001.1101.1" + + "" + + "" + + "001.1101.1" + + "" + + ""); + + var reader = new SoilLayer2DReader(); + + // Call + var result = reader.Read(xmlDoc); + + // Assert + Assert.AreEqual(2, result.OuterLoop.Count()); + Assert.AreEqual(result.OuterLoop.ElementAt(0), result.OuterLoop.ElementAt(1)); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/SoilProfile2DReaderTest.cs =================================================================== diff -u -rd2b5b334c49948fa49297a1d24c13bc98aa6ee1e -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/SoilProfile2DReaderTest.cs (.../SoilProfile2DReaderTest.cs) (revision d2b5b334c49948fa49297a1d24c13bc98aa6ee1e) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/SoilProfile/SoilProfile2DReaderTest.cs (.../SoilProfile2DReaderTest.cs) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Xml; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Piping.IO.Exceptions; @@ -14,14 +15,14 @@ private MockRepository mocks; private IRowBasedDatabaseReader reader; - private readonly byte[] someGeometry = StringGeometryHelper.GetBytes("" + - "" + - "001.1101.1" + - "" + - "" + - "001.1101.1" + - "" + - ""); + private readonly byte[] someGeometry = StringGeometryHelper.GetByteArray("" + + "" + + "001.1101.1" + + "" + + "" + + "001.1101.1" + + "" + + ""); [SetUp] public void SetUp() @@ -110,12 +111,10 @@ } [Test] - [TestCase(new byte[0])] - [TestCase(null)] - public void ReadFrom_EmptyGeometry_ThrowsPipingSoilProfileReadException(byte[] geometry) + public void ReadFrom_NullGeometry_ThrowsPipingSoilProfileReadException() { // Setup - SetExpectations(1, "", 0.0, 1.0, 0.0, 0.0, 0.0, geometry); + SetExpectations(1, "", 0.0, 1.0, 0.0, 0.0, 0.0, null); mocks.ReplayAll(); @@ -124,6 +123,24 @@ // Assert var exception = Assert.Throws(test); + StringAssert.StartsWith("De geometrie is leeg.", exception.Message); + + mocks.VerifyAll(); + } + + [Test] + public void ReadFrom_EmptyGeometry_ThrowsPipingSoilProfileReadException() + { + // Setup + SetExpectations(1, "", 0.0, 1.0, 0.0, 0.0, 0.0, new byte[0]); + + mocks.ReplayAll(); + + // Call + TestDelegate test = () => SoilProfile2DReader.ReadFrom(reader); + + // Assert + var exception = Assert.Throws(test); Assert.AreEqual("Het XML-document dat de geometrie beschrijft voor de laag is niet geldig.", exception.Message); mocks.VerifyAll(); Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/TestHelpers/StringGeometryHelper.cs =================================================================== diff -u -ra6ba313236d0ff8d2f219fc8249b700b1eade338 -r0047bcf51f94a295f3e4854f9b93594ad01a9e70 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/TestHelpers/StringGeometryHelper.cs (.../StringGeometryHelper.cs) (revision a6ba313236d0ff8d2f219fc8249b700b1eade338) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/TestHelpers/StringGeometryHelper.cs (.../StringGeometryHelper.cs) (revision 0047bcf51f94a295f3e4854f9b93594ad01a9e70) @@ -1,11 +1,18 @@ using System; +using System.IO; +using System.Xml.Linq; namespace Ringtoets.Piping.IO.Test.TestHelpers { - public class StringGeometryHelper + public static class StringGeometryHelper { - public static byte[] GetBytes(string str) + public static XDocument GetXmlDocument(string str) { + return XDocument.Load(new MemoryStream(GetByteArray(str))); + } + + public static byte[] GetByteArray(string str) + { byte[] bytes = new byte[str.Length * sizeof(char)]; Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); return bytes;