Index: Core/Common/src/Core.Common.Utils/Properties/Resources.Designer.cs =================================================================== diff -u -rbeb6414981b7d4df7cb304d86e5dbacd729b5f77 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Core/Common/src/Core.Common.Utils/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision beb6414981b7d4df7cb304d86e5dbacd729b5f77) +++ Core/Common/src/Core.Common.Utils/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -97,6 +97,15 @@ } /// + /// Looks up a localized string similar to Regel bevat te veel tekst om in het RAM geheugen opgeslagen te worden.. + /// + public static string Error_Line_too_big_for_RAM { + get { + return ResourceManager.GetString("Error_Line_too_big_for_RAM", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Bestandspad mag niet de volgende tekens bevatten: {0}. /// public static string Error_Path_cannot_contain_Characters_0_ { Index: Core/Common/src/Core.Common.Utils/Properties/Resources.resx =================================================================== diff -u -rbeb6414981b7d4df7cb304d86e5dbacd729b5f77 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Core/Common/src/Core.Common.Utils/Properties/Resources.resx (.../Resources.resx) (revision beb6414981b7d4df7cb304d86e5dbacd729b5f77) +++ Core/Common/src/Core.Common.Utils/Properties/Resources.resx (.../Resources.resx) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -147,4 +147,7 @@ Fout bij het schrijven naar bestand '{0}': {1} + + Regel bevat te veel tekst om in het RAM geheugen opgeslagen te worden. + \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingCharacteristicPointsLocation.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingCharacteristicPointsLocation.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/PipingCharacteristicPointsLocation.cs (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,31 @@ +using System; + +namespace Ringtoets.Piping.Data +{ + /// + /// This class represents a location for which there are points along the surface line + /// which are characterizing for that surface line. + /// + public class PipingCharacteristicPointsLocation + { + /// + /// Creates an instance of . + /// + /// The name of the location for which the + /// defines characteristic points. + public PipingCharacteristicPointsLocation(string name) + { + if (name == null) + { + throw new ArgumentNullException("name", "Cannot make a definition of characteristic points for an unknown location."); + } + Name = name; + } + + /// + /// Gets the name of the location for which the defines + /// characteristic points. + /// + public string Name { get; private set; } + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj =================================================================== diff -u -rc8848af0c6f8780634dcce2013e606f090da6577 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision c8848af0c6f8780634dcce2013e606f090da6577) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/Ringtoets.Piping.Data.csproj (.../Ringtoets.Piping.Data.csproj) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -59,6 +59,7 @@ + Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingCharacteristicPointsCsvReader.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingCharacteristicPointsCsvReader.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingCharacteristicPointsCsvReader.cs (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,208 @@ +// Copyright (C) Stichting Deltares 2016. 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.IO; +using Core.Common.Utils; +using Core.Common.Utils.Builders; +using Ringtoets.Piping.IO.Exceptions; +using Ringtoets.Piping.IO.Properties; + +namespace Ringtoets.Piping.IO +{ + /// + /// File reader for a plain text file in comma-separated values format (*.csv), containing + /// data specifying characteristic points. + /// Expects data to be specified in the following format: + /// + /// LocationID;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek_sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;X_Dijktafelhoogte;Y_Dijktafelhoogte;Z_Dijktafelhoogte;Volgnummer + /// + /// Where {LocationID} has to be a particular accepted text, {Volgnummer} is ignored, and n triplets of doubles form the + /// 3D coordinates defining each characteristic point. + /// + public class PipingCharacteristicPointsCsvReader : IDisposable + { + private const string expectedHeader = "locationid;x_maaiveld binnenwaarts;y_maaiveld binnenwaarts;z_maaiveld binnenwaarts;x_insteek sloot polderzijde;y_insteek sloot polderzijde;z_insteek sloot polderzijde;x_slootbodem polderzijde;y_slootbodem polderzijde;z_slootbodem polderzijde;x_slootbodem dijkzijde;y_slootbodem dijkzijde;z_slootbodem dijkzijde;x_insteek sloot dijkzijde;y_insteek sloot dijkzijde;z_insteek sloot dijkzijde;x_teen dijk binnenwaarts;y_teen dijk binnenwaarts;z_teen dijk binnenwaarts;x_kruin binnenberm;y_kruin binnenberm;z_kruin binnenberm;x_insteek binnenberm;y_insteek binnenberm;z_insteek binnenberm;x_kruin binnentalud;y_kruin binnentalud;z_kruin binnentalud;x_verkeersbelasting kant binnenwaarts;y_verkeersbelasting kant binnenwaarts;z_verkeersbelasting kant binnenwaarts;x_verkeersbelasting kant buitenwaarts;y_verkeersbelasting kant buitenwaarts;z_verkeersbelasting kant buitenwaarts;x_kruin buitentalud;y_kruin buitentalud;z_kruin buitentalud;x_insteek buitenberm;y_insteek buitenberm;z_insteek buitenberm;x_kruin buitenberm;y_kruin buitenberm;z_kruin buitenberm;x_teen dijk buitenwaarts;y_teen dijk buitenwaarts;z_teen dijk buitenwaarts;x_maaiveld buitenwaarts;y_maaiveld buitenwaarts;z_maaiveld buitenwaarts;x_dijktafelhoogte;y_dijktafelhoogte;z_dijktafelhoogte;volgnummer"; + private const char separator = ';'; + private readonly string filePath; + + /// + /// Lower case string representations of the known characteristic point types. + /// + private readonly string[] characteristicPointKeys = + { + "maaiveld binnenwaarts", + "insteek sloot polderzijde", + "slootbodem polderzijde", + "slootbodem dijkzijde", + "insteek sloot dijkzijde", + "teen dijk binnenwaarts", + "kruin binnenberm", + "insteek binnenberm", + "kruin binnentalud", + "verkeersbelasting kant binnenwaarts", + "verkeersbelasting kant buitenwaarts", + "kruin buitentalud", + "insteek buitenberm", + "kruin buitenberm", + "teen dijk buitenwaarts", + "maaiveld buitenwaarts", + "dijktafelhoogte" + }; + + private StreamReader fileReader; + + /// + /// Initializes a new instance of using + /// the given . + /// + /// The path to use for reading characteristic points. + /// is invalid. + public PipingCharacteristicPointsCsvReader(string path) + { + FileUtils.ValidateFilePath(path); + + filePath = path; + } + + /// + /// Reads the file to determine the number of available + /// data rows. + /// + /// A value greater than or equal to 0. + /// A critical error has occurred, which may be caused by: + /// + /// File cannot be found at specified path. + /// The specified path is invalid, such as being on an unmapped drive. + /// Some other I/O related issue occurred, such as: path includes an incorrect + /// or invalid syntax for file name, directory name, or volume label. + /// There is insufficient memory to allocate a buffer for the returned string. + /// File incompatible for importing surface lines. + /// + /// + public int GetLocationsCount() + { + using (var reader = StreamReaderHelper.InitializeStreamReader(filePath)) + { + ValidateHeader(reader, 1); + + return CountNonEmptyLines(reader, 2); + } + } + + /// + /// Validates the header of the file. + /// + /// The reader, which is currently at the header row. + /// Row index used in error messaging. + /// The header is not in the required format. + private void ValidateHeader(TextReader reader, int currentLine) + { + var header = ReadLineAndHandleIOExceptions(reader, currentLine); + if (header != null) + { + if (!IsHeaderValid(header)) + { + throw CreateCriticalFileReadException(currentLine, Resources.PipingCharacteristicPointsCsvReader_File_invalid_header); + } + } + else + { + throw CreateCriticalFileReadException(currentLine, Core.Common.Utils.Properties.Resources.Error_File_empty); + } + } + + /// + /// Reads the next line and handles I/O exceptions. + /// + /// The opened text file reader. + /// Row number for error messaging. + /// The read line, or null when at the end of the file. + /// An critical I/O exception occurred. + private string ReadLineAndHandleIOExceptions(TextReader reader, int currentLine) + { + try + { + return reader.ReadLine(); + } + catch (OutOfMemoryException e) + { + throw CreateCriticalFileReadException(currentLine, Core.Common.Utils.Properties.Resources.Error_Line_too_big_for_RAM, e); + } + catch (IOException e) + { + var message = new FileReaderErrorMessageBuilder(filePath).Build(string.Format(Core.Common.Utils.Properties.Resources.Error_General_IO_ErrorMessage_0_, e.Message)); + throw new CriticalFileReadException(message, e); + } + } + + /// + /// Throws a configured instance of . + /// + /// The line number being read. + /// The critical error message. + /// Optional: exception that caused this exception to be thrown. + /// New with message and inner exception set. + private CriticalFileReadException CreateCriticalFileReadException(int currentLine, string criticalErrorMessage, Exception innerException = null) + { + string locationDescription = string.Format(Resources.TextFile_On_LineNumber_0_, currentLine); + var message = new FileReaderErrorMessageBuilder(filePath).WithLocation(locationDescription) + .Build(criticalErrorMessage); + return new CriticalFileReadException(message, innerException); + } + + private bool IsHeaderValid(string header) + { + return expectedHeader == header.ToLowerInvariant(); + } + + /// + /// Counts the remaining non-empty lines. + /// + /// The reader at the row from which counting should start. + /// The current line, used for error messaging. + /// An integer greater than or equal to 0, being the number of surfaceline rows. + /// An I/O exception occurred. + private int CountNonEmptyLines(TextReader reader, int currentLine) + { + int count = 0, lineNumberForMessage = currentLine; + string line; + while ((line = ReadLineAndHandleIOExceptions(reader, lineNumberForMessage)) != null) + { + if (!String.IsNullOrWhiteSpace(line)) + { + count++; + } + lineNumberForMessage++; + } + return count; + } + + public void Dispose() + { + if (fileReader != null) + { + fileReader.Dispose(); + fileReader = null; + } + } + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSurfaceLinesCsvReader.cs =================================================================== diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -93,7 +93,7 @@ /// public int GetSurfaceLinesCount() { - using (var reader = InitializeStreamReader(filePath)) + using (var reader = StreamReaderHelper.InitializeStreamReader(filePath)) { ValidateHeader(reader, 1); @@ -129,7 +129,7 @@ { if (fileReader == null) { - fileReader = InitializeStreamReader(filePath); + fileReader = StreamReaderHelper.InitializeStreamReader(filePath); ValidateHeader(fileReader, 1); lineNumber = 2; @@ -140,20 +140,7 @@ { try { - var tokenizedString = TokenizeString(readText); - - var surfaceLineName = GetSurfaceLineName(tokenizedString); - var points = GetSurfaceLinePoints(tokenizedString, surfaceLineName); - - var surfaceLine = new RingtoetsPipingSurfaceLine - { - Name = surfaceLineName - }; - surfaceLine.SetGeometry(points); - - CheckIfGeometryIsValid(surfaceLine); - - return surfaceLine; + return CreateRingtoetsPipingSurfaceLine(readText); } finally { @@ -164,6 +151,24 @@ return null; } + private RingtoetsPipingSurfaceLine CreateRingtoetsPipingSurfaceLine(string readText) + { + var tokenizedString = TokenizeString(readText); + + var surfaceLineName = GetSurfaceLineName(tokenizedString); + var points = GetSurfaceLinePoints(tokenizedString, surfaceLineName); + + var surfaceLine = new RingtoetsPipingSurfaceLine + { + Name = surfaceLineName + }; + surfaceLine.SetGeometry(points); + + CheckIfGeometryIsValid(surfaceLine); + + return surfaceLine; + } + public void Dispose() { if (fileReader != null) @@ -292,36 +297,6 @@ } /// - /// Initializes the stream reader for a UTF8 encoded file. - /// - /// The path to the file to be read. - /// A UTF8 encoding configured stream reader opened on . - /// File/directory cannot be found or - /// some other I/O related problem occurred. - private static StreamReader InitializeStreamReader(string path) - { - try - { - return new StreamReader(path); - } - catch (FileNotFoundException e) - { - string message = new FileReaderErrorMessageBuilder(path).Build(UtilsResources.Error_File_does_not_exist); - throw new CriticalFileReadException(message, e); - } - catch (DirectoryNotFoundException e) - { - string message = new FileReaderErrorMessageBuilder(path).Build(UtilsResources.Error_Directory_missing); - throw new CriticalFileReadException(message, e); - } - catch (IOException e) - { - var message = new FileReaderErrorMessageBuilder(path).Build(string.Format(UtilsResources.Error_General_IO_ErrorMessage_0_, e.Message)); - throw new CriticalFileReadException(message, e); - } - } - - /// /// Validates the header of the file. /// /// The reader, which is currently at the header row. @@ -427,7 +402,7 @@ } catch (OutOfMemoryException e) { - throw CreateCriticalFileReadException(currentLine, UtilsResources.Error_File_does_not_exist, e); + throw CreateCriticalFileReadException(currentLine, UtilsResources.Error_Line_too_big_for_RAM, e); } catch (IOException e) { @@ -446,7 +421,7 @@ return false; } - // CHeck for valid 1st coordinate in header: + // Check for valid 1st coordinate in header: bool valid = true; for (int i = 0; i < expectedFirstCoordinateHeader.Length && valid; i++) { Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs =================================================================== diff -u -rc8848af0c6f8780634dcce2013e606f090da6577 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision c8848af0c6f8780634dcce2013e606f090da6577) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.17929 +// Runtime Version:4.0.30319.34209 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -107,6 +107,15 @@ } /// + /// Looks up a localized string similar to Het bestand is niet geschikt om profielmetingen uit te lezen: koptekst komt niet overeen met wat verwacht wordt.. + /// + public static string PipingCharacteristicPointsCsvReader_File_invalid_header { + get { + return ResourceManager.GetString("PipingCharacteristicPointsCsvReader_File_invalid_header", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Kan de geometrie van laag nummer '{0}' in profiel '{1}' niet interpreteren.. /// public static string PipingSoilProfileReader_CouldNotParseGeometryOfLayer_0_InProfile_1_ { Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx =================================================================== diff -u -r654d3a712eedbdeea718dc0448c5544f09e053cd -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 654d3a712eedbdeea718dc0448c5544f09e053cd) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Properties/Resources.resx (.../Resources.resx) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -180,4 +180,7 @@ ondergrondschematisering '{0}' + + Het bestand is niet geschikt om profielmetingen uit te lezen: koptekst komt niet overeen met wat verwacht wordt. + \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj =================================================================== diff -u -rc8848af0c6f8780634dcce2013e606f090da6577 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj (.../Ringtoets.Piping.IO.csproj) (revision c8848af0c6f8780634dcce2013e606f090da6577) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/Ringtoets.Piping.IO.csproj (.../Ringtoets.Piping.IO.csproj) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -51,6 +51,7 @@ + @@ -65,6 +66,7 @@ Resources.resx + Index: Ringtoets/Piping/src/Ringtoets.Piping.IO/StreamReaderHelper.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.IO/StreamReaderHelper.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.IO/StreamReaderHelper.cs (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,44 @@ +using System; +using System.IO; +using Core.Common.Utils.Builders; +using Core.Common.Utils.Properties; +using Ringtoets.Piping.IO.Exceptions; + +namespace Ringtoets.Piping.IO +{ + /// + /// This class provides helper functions for reading UTF8 encoded files. + /// + public static class StreamReaderHelper + { + /// + /// Initializes the stream reader for a UTF8 encoded file. + /// + /// The path to the file to be read. + /// A UTF8 encoding configured stream reader opened on . + /// File/directory cannot be found or + /// some other I/O related problem occurred. + public static StreamReader InitializeStreamReader(string path) + { + try + { + return new StreamReader(path); + } + catch (FileNotFoundException e) + { + string message = new FileReaderErrorMessageBuilder(path).Build(Resources.Error_File_does_not_exist); + throw new CriticalFileReadException(message, e); + } + catch (DirectoryNotFoundException e) + { + string message = new FileReaderErrorMessageBuilder(path).Build(Resources.Error_Directory_missing); + throw new CriticalFileReadException(message, e); + } + catch (IOException e) + { + var message = new FileReaderErrorMessageBuilder(path).Build(String.Format(Resources.Error_General_IO_ErrorMessage_0_, e.Message)); + throw new CriticalFileReadException(message, e); + } + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingCharacteristicPointsLocationTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingCharacteristicPointsLocationTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingCharacteristicPointsLocationTest.cs (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,31 @@ +using System; +using NUnit.Framework; + +namespace Ringtoets.Piping.Data.Test +{ + [TestFixture] + public class PipingCharacteristicPointsLocationTest + { + [Test] + public void Constructor_WithNullName_ThrowsArgumentNullException() + { + // Call + TestDelegate test = () => new PipingCharacteristicPointsLocation(null); + + // Assert + Assert.Throws(test); + } + + [Test] + [TestCase("")] + [TestCase("Name")] + public void Constructor_WithName_ThrowsArgumentNullException(string name) + { + // Call + var location = new PipingCharacteristicPointsLocation(name); + + // Assert + Assert.AreEqual(name, location.Name); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj =================================================================== diff -u -rc7519c6ad1ca1d754f657856bc88057675cec868 -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision c7519c6ad1ca1d754f657856bc88057675cec868) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/Ringtoets.Piping.Data.Test.csproj (.../Ringtoets.Piping.Data.Test.csproj) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -63,6 +63,7 @@ + Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingCharacteristicPointsCsvReaderTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingCharacteristicPointsCsvReaderTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/PipingCharacteristicPointsCsvReaderTest.cs (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,180 @@ +using System; +using System.IO; +using Core.Common.TestUtil; +using Core.Common.Utils.Builders; +using NUnit.Framework; +using Ringtoets.Piping.IO.Exceptions; +using UtilsResources = Core.Common.Utils.Properties.Resources; + +namespace Ringtoets.Piping.IO.Test +{ + public class PipingCharacteristicPointsCsvReaderTest + { + private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Piping.IO, "CharacteristicPoints" + Path.DirectorySeparatorChar); + + [Test] + [TestCase("")] + [TestCase(null)] + [TestCase(" ")] + public void ParameterdConstructor_InvalidStringArgument_ThrowsArgumentException(string path) + { + // Call + TestDelegate call = () => new PipingCharacteristicPointsCsvReader(path); + + // Assert + var exception = Assert.Throws(call); + var expectedMessage = new FileReaderErrorMessageBuilder(path).Build(UtilsResources.Error_Path_must_be_specified); + Assert.AreEqual(expectedMessage, exception.Message); + } + + [Test] + public void ParameterdConstructor_InvalidPathCharactersInPath_ThrowsArgumentException() + { + // Setup + string path = Path.Combine(testDataPath, "TwoValidLocations.csv"); + + var invalidCharacters = Path.GetInvalidPathChars(); + + var corruptPath = path.Replace('V', invalidCharacters[0]); + + // Call + TestDelegate call = () => new PipingCharacteristicPointsCsvReader(corruptPath); + + // Assert + var exception = Assert.Throws(call); + var expectedMessage = new FileReaderErrorMessageBuilder(corruptPath).Build(String.Format(UtilsResources.Error_Path_cannot_contain_Characters_0_, + String.Join(", ", Path.GetInvalidFileNameChars()))); + Assert.AreEqual(expectedMessage, exception.Message); + } + + [Test] + public void ParametersConstructor_PathToFolder_ThrowsArgumentException() + { + // Call + TestDelegate call = () => new PipingCharacteristicPointsCsvReader(testDataPath); + + // Assert + var exception = Assert.Throws(call); + var expectedMessage = new FileReaderErrorMessageBuilder(testDataPath).Build(UtilsResources.Error_Path_must_not_point_to_folder); + Assert.AreEqual(expectedMessage, exception.Message); + } + + [Test] + public void ParameterdConstructor_AnyPath_ExpectedValues() + { + // Setup + const string fakeFilePath = @"I\Dont\Really\Exist"; + + // Call + using (var reader = new PipingCharacteristicPointsCsvReader(fakeFilePath)) + { + // Assert + Assert.IsInstanceOf(reader); + } + } + + [Test] + [TestCase("0locations.krp.csv", 0)] + [TestCase("1location.krp.csv", 1)] + [TestCase("2locations_empty_line.krp.csv", 2)] + public void GetLocationsCount_DifferentFiles_ShouldReturnNumberOfLocations(string fileName, int expectedCount) + { + // Setup + string path = Path.Combine(testDataPath, fileName); + using (var reader = new PipingCharacteristicPointsCsvReader(path)) + { + // Call + var result = reader.GetLocationsCount(); + + // Assert + Assert.AreEqual(expectedCount, result); + } + } + + [Test] + public void GetLocationsCount_FileCannotBeFound_ThrowCriticalFileReadException() + { + // Setup + string path = Path.Combine(testDataPath, "I_do_not_exist.csv"); + + // Precondition + Assert.IsFalse(File.Exists(path)); + + using (var reader = new PipingCharacteristicPointsCsvReader(path)) + { + // Call + TestDelegate call = () => reader.GetLocationsCount(); + + // Assert + var exception = Assert.Throws(call); + var expectedError = new FileReaderErrorMessageBuilder(path).Build(UtilsResources.Error_File_does_not_exist); + Assert.AreEqual(expectedError, exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + } + + [Test] + public void GetLocationsCount_DirectoryCannotBeFound_ThrowCriticalFileReadException() + { + // Setup + string path = Path.Combine(testDataPath, "..", "this_folder_does_not_exist", "I_do_not_exist.csv"); + + // Precondition + Assert.IsFalse(File.Exists(path)); + + using (var reader = new PipingCharacteristicPointsCsvReader(path)) + { + // Call + TestDelegate call = () => reader.GetLocationsCount(); + + // Assert + var exception = Assert.Throws(call); + var expectedMessage = new FileReaderErrorMessageBuilder(path).Build(UtilsResources.Error_Directory_missing); + Assert.AreEqual(expectedMessage, exception.Message); + Assert.IsInstanceOf(exception.InnerException); + } + } + + [Test] + public void GetLocationsCount_EmptyFile_ThrowCriticalFileReadException() + { + // Setup + string path = Path.Combine(testDataPath, "empty.csv"); + + // Precondition + Assert.IsTrue(File.Exists(path)); + + using (var reader = new PipingCharacteristicPointsCsvReader(path)) + { + // Call + TestDelegate call = () => reader.GetLocationsCount(); + + // Assert + var exception = Assert.Throws(call); + var expectedMessage = new FileReaderErrorMessageBuilder(path).WithLocation("op regel 1").Build(UtilsResources.Error_File_empty); + Assert.AreEqual(expectedMessage, exception.Message); + } + } + + [Test] + public void GetLocationsCount_InvalidHeader1_ThrowCriticalFileReadException() + { + // Setup + string path = Path.Combine(testDataPath, "1location_invalid_header.krp.csv"); + + // Precondition + Assert.IsTrue(File.Exists(path)); + + using (var reader = new PipingCharacteristicPointsCsvReader(path)) + { + // Call + TestDelegate call = () => reader.GetLocationsCount(); + + // Assert + var exception = Assert.Throws(call); + var expectedMessage = new FileReaderErrorMessageBuilder(path).WithLocation("op regel 1").Build(Properties.Resources.PipingCharacteristicPointsCsvReader_File_invalid_header); + Assert.AreEqual(expectedMessage, exception.Message); + } + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj =================================================================== diff -u -r654d3a712eedbdeea718dc0448c5544f09e053cd -r71e6fa1d924328063813f357c9b737a8f9084491 --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj (.../Ringtoets.Piping.IO.Test.csproj) (revision 654d3a712eedbdeea718dc0448c5544f09e053cd) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/Ringtoets.Piping.IO.Test.csproj (.../Ringtoets.Piping.IO.Test.csproj) (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -69,6 +69,7 @@ + Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/0locations.krp.csv =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/0locations.krp.csv (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/0locations.krp.csv (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,3 @@ +LocationID;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;X_Dijktafelhoogte;Y_Dijktafelhoogte;Z_Dijktafelhoogte;Volgnummer + + Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/1location.krp.csv =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/1location.krp.csv (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/1location.krp.csv (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,2 @@ +LocationID;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;X_Dijktafelhoogte;Y_Dijktafelhoogte;Z_Dijktafelhoogte;Volgnummer +dijkring10_dwp28_6;100;0;0.74;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;43.71;0;0.18;-1;-1;-1;-1;-1;-1;36.17;0;2.89;36.17;0;2.89;33.67;0;2.986;32.72;0;2.96;-1;-1;-1;-1;-1;-1;24.72;0;0.52;0;0;0.47;12.96;0;-0.07;1 Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/1location_invalid_header.krp.csv =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/1location_invalid_header.krp.csv (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/1location_invalid_header.krp.csv (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,2 @@ +SomethingWrong;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;X_Dijktafelhoogte;Y_Dijktafelhoogte;Z_Dijktafelhoogte;Volgnummer +dijkring10_dwp28_6;100;0;0.74;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;-1;43.71;0;0.18;-1;-1;-1;-1;-1;-1;36.17;0;2.89;36.17;0;2.89;33.67;0;2.986;32.72;0;2.96;-1;-1;-1;-1;-1;-1;24.72;0;0.52;0;0;0.47;12.96;0;-0.07;1 Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/2locations_empty_line.krp.csv =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/2locations_empty_line.krp.csv (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/2locations_empty_line.krp.csv (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1,4 @@ +LocationID;X_Maaiveld binnenwaarts;Y_Maaiveld binnenwaarts;Z_Maaiveld binnenwaarts;X_Insteek sloot polderzijde;Y_Insteek sloot polderzijde;Z_Insteek sloot polderzijde;X_Slootbodem polderzijde;Y_Slootbodem polderzijde;Z_Slootbodem polderzijde;X_Slootbodem dijkzijde;Y_Slootbodem dijkzijde;Z_Slootbodem dijkzijde;X_Insteek sloot dijkzijde;Y_Insteek sloot dijkzijde;Z_Insteek sloot dijkzijde;X_Teen dijk binnenwaarts;Y_Teen dijk binnenwaarts;Z_Teen dijk binnenwaarts;X_Kruin binnenberm;Y_Kruin binnenberm;Z_Kruin binnenberm;X_Insteek binnenberm;Y_Insteek binnenberm;Z_Insteek binnenberm;X_Kruin binnentalud;Y_Kruin binnentalud;Z_Kruin binnentalud;X_Verkeersbelasting kant binnenwaarts;Y_Verkeersbelasting kant binnenwaarts;Z_Verkeersbelasting kant binnenwaarts;X_Verkeersbelasting kant buitenwaarts;Y_Verkeersbelasting kant buitenwaarts;Z_Verkeersbelasting kant buitenwaarts;X_Kruin buitentalud;Y_Kruin buitentalud;Z_Kruin buitentalud;X_Insteek buitenberm;Y_Insteek buitenberm;Z_Insteek buitenberm;X_Kruin buitenberm;Y_Kruin buitenberm;Z_Kruin buitenberm;X_Teen dijk buitenwaarts;Y_Teen dijk buitenwaarts;Z_Teen dijk buitenwaarts;X_Maaiveld buitenwaarts;Y_Maaiveld buitenwaarts;Z_Maaiveld buitenwaarts;X_Dijktafelhoogte;Y_Dijktafelhoogte;Z_Dijktafelhoogte;Volgnummer +dijkring10_dwp32_7;100;0;-0.63;60.83;0;-0.57;59.36;0;-1.87;57.99;0;-1.9;55.37;0;-0.31;55.37;0;-0.31;-1;-1;-1;-1;-1;-1;40.17;0;2.63;40.85;0;2.44;38.35;0;2.623;35.95;0;2.61;-1;-1;-1;-1;-1;-1;29.1;0;-0.2;0;0;-0.71;23.703;0;-1.5;3 + +dijkring10_dwp35_2;100;0;-0.47;58.42;0;-0.6;56.2;0;-1.98;56.2;0;-1.98;53.48;0;-0.49;53.48;0;-0.49;-1;-1;-1;-1;-1;-1;38.17;0;3.04;37.73;0;3.13;35.23;0;3.253;32.77;0;3.11;-1;-1;-1;-1;-1;-1;19.61;0;-0.05;0;0;-0.33;17.32;0;-1.52;4 Index: Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/empty.csv =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/empty.csv (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.IO.Test/test-data/CharacteristicPoints/empty.csv (revision 71e6fa1d924328063813f357c9b737a8f9084491) @@ -0,0 +1 @@ \ No newline at end of file