Index: Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj =================================================================== diff -u -r60bd3c063c8173f762c5762096efa38b87f780ed -r653c18f73b4404d9ac58d818845474d68e48635d --- Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision 60bd3c063c8173f762c5762096efa38b87f780ed) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Ringtoets.Common.IO.csproj (.../Ringtoets.Common.IO.csproj) (revision 653c18f73b4404d9ac58d818845474d68e48635d) @@ -70,7 +70,7 @@ - + Fisheye: Tag 653c18f73b4404d9ac58d818845474d68e48635d refers to a dead (removed) revision in file `Ringtoets/Common/src/Ringtoets.Common.IO/Structures/HeightStructuresCharacteristicsCsvReader.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresCharacteristicsCsvReader.cs =================================================================== diff -u --- Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresCharacteristicsCsvReader.cs (revision 0) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresCharacteristicsCsvReader.cs (revision 653c18f73b4404d9ac58d818845474d68e48635d) @@ -0,0 +1,519 @@ +// 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 System.Linq; +using Core.Common.IO.Exceptions; +using Core.Common.IO.Readers; +using Core.Common.Utils; +using Core.Common.Utils.Builders; +using CoreCommonUtilsResources = Core.Common.Utils.Properties.Resources; + +namespace Ringtoets.Common.IO.Structures +{ + /// + /// File reader for a plain text file in comma-separated values format (*.csv) containing + /// data specifying characteristics of height structures. + /// + public class StructuresCharacteristicsCsvReader : IDisposable + { + private const char separator = ';'; + private readonly string filePath; + + private readonly string[] requiredHeaderColumns = + { + "identificatie", + "kunstwerken.identificatie", + "numeriekeWaarde", + "standarddeviatie.variance", + "boolean" + }; + + private int locationIdIndex, parameterIdIndex, numericValueIndex, varianceValueIndex, varianceTypeIndex; + + private int lineNumber; + private StreamReader fileReader; + + /// + /// Creates a new instance of + /// and opens a given file path. + /// + /// The path to the file to be read. + /// Thrown when is invalid. + public StructuresCharacteristicsCsvReader(string path) + { + FileUtils.ValidateFilePath(path); + + filePath = path; + } + + /// + /// Counts the number of parameter definitions found in the file. + /// + /// An integer greater than or equal to 0, being the number of parameter rows. + /// File/directory cannot be found or + /// some other I/O related problem occurred or the header is not in the required format. + public int GetLineCount() + { + using (var reader = StreamReaderHelper.InitializeStreamReader(filePath)) + { + ValidateHeader(reader, 1); + + return CountNonEmptyLines(reader, 2); + } + } + + /// + /// Reads the next structure parameter from file. + /// + /// The next based on the read file, + /// or null when at the end of the file. + /// + /// Thrown when either: + /// + /// The file or directory cannot be found. + /// The file is empty. + /// Some I/O related problem occurred. + /// The header is not in the required format. + /// + /// Thrown when either: + /// + /// The line does not contain the separator character. + /// Location id field is empty or consists out of only white spaces. + /// Parameter id field is empty or consists out of only white spaces. + /// Numeric value field is not a number or too large/small to be represented as . + /// Variance value field is not a number or too large/small to be represented as . + /// Boolean field is not a valid value. + /// + public StructuresParameterRow ReadLine() + { + if (fileReader == null) + { + fileReader = StreamReaderHelper.InitializeStreamReader(filePath); + + lineNumber = 1; + IndexFile(fileReader); + lineNumber++; + } + + string readText = ReadNextNonEmptyLine(fileReader); + if (readText != null) + { + try + { + return CreateStructuresParameterRow(readText); + } + finally + { + lineNumber++; + } + } + + return null; + } + + public void Dispose() + { + if (fileReader != null) + { + fileReader.Dispose(); + fileReader = null; + } + } + + /// + /// 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) + { + string[] tokenizedHeader = GetTokenizedHeader(reader); + const int uninitializedValue = -999; + int[] requiredHeaderColumnIndices = GetRequiredHeaderColumnIndices(uninitializedValue, tokenizedHeader); + ValidateRequiredColumnIndices(currentLine, requiredHeaderColumnIndices, uninitializedValue); + } + + /// + /// 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 parameter 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; + } + + /// + /// 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, CoreCommonUtilsResources.Error_Line_too_big_for_RAM, e); + } + catch (IOException e) + { + string errorMessage = string.Format((string)CoreCommonUtilsResources.Error_General_IO_ErrorMessage_0_, + e.Message); + var fullErrorMessage = new FileReaderErrorMessageBuilder(filePath).Build(errorMessage); + throw new CriticalFileReadException(fullErrorMessage, e); + } + } + + /// + /// Reads the header and sets the internal indices of the required header columns. + /// + /// The reader used to read the file. + /// The file is empty or some I/O exception + /// occurred or the header is not in the required format. + private void IndexFile(TextReader reader) + { + string[] tokenizedHeader = GetTokenizedHeader(reader); + + const int uninitializedValue = -999; + int[] requiredHeaderColumnIndices = GetRequiredHeaderColumnIndices(uninitializedValue, tokenizedHeader); + ValidateRequiredColumnIndices(lineNumber, requiredHeaderColumnIndices, uninitializedValue); + + SetColumnIndices(requiredHeaderColumnIndices); + } + + /// + /// Tokenizes the file header. + /// + /// The reader used to read the file. + /// The header split based on . + /// The file is empty or some I/O exception + /// occurred. + private string[] GetTokenizedHeader(TextReader reader) + { + var header = ReadLineAndHandleIOExceptions(reader, lineNumber); + if (header == null) + { + throw CreateCriticalFileReadException(lineNumber, CoreCommonUtilsResources.Error_File_empty); + } + + return header.Split(separator) + .Select(s => s.Trim().ToLowerInvariant()) + .ToArray(); + } + + private int[] GetRequiredHeaderColumnIndices(int initialColumnIndexValue, string[] tokenizedHeader) + { + int[] requiredHeaderColumnIndices = Enumerable.Repeat(initialColumnIndexValue, requiredHeaderColumns.Length) + .ToArray(); + for (int columnIndex = 0; columnIndex < tokenizedHeader.Length; columnIndex++) + { + string columnName = tokenizedHeader[columnIndex]; + int index = Array.IndexOf(requiredHeaderColumns, columnName); + if (index != -1) + { + // TODO: same column multiple times! + requiredHeaderColumnIndices[index] = columnIndex; + } + } + return requiredHeaderColumnIndices; + } + + /// + /// + /// + /// + /// + /// + /// The header is not in the required format. + private void ValidateRequiredColumnIndices(int currentLine, int[] requiredHeaderColumnIndices, int uninitializedValue) + { + if (requiredHeaderColumnIndices.Any(i => i == uninitializedValue)) + { + throw CreateCriticalFileReadException(currentLine, string.Format("Het bestand is niet geschikt om kunstwerken parameters uit te lezen (Verwachte koptekst moet de volgende kolommen bevatten: {0}.", + string.Join(", ", requiredHeaderColumns))); + } + } + + private void SetColumnIndices(int[] requiredHeaderColumnIndices) + { + locationIdIndex = requiredHeaderColumnIndices[0]; + parameterIdIndex = requiredHeaderColumnIndices[1]; + numericValueIndex = requiredHeaderColumnIndices[2]; + varianceValueIndex = requiredHeaderColumnIndices[3]; + varianceTypeIndex = requiredHeaderColumnIndices[4]; + } + + /// + /// Reads lines from file until the first non-white line is hit. + /// + /// The next line which is not a white line, or null when no non-white + /// line could be found before the end of file. + /// An critical I/O exception occurred. + private string ReadNextNonEmptyLine(StreamReader reader) + { + string readText; + while ((readText = ReadLineAndHandleIOExceptions(reader, lineNumber)) != null) + { + if (string.IsNullOrWhiteSpace(readText)) + { + lineNumber++; + } + else + { + break; + } + } + return readText; + } + + /// + /// Creates the structures parameter row. + /// + /// The read text. + /// + /// Thrown when either: + /// + /// does not contain the separator character. + /// Location id field is empty or consists out of only white spaces. + /// Parameter id field is empty or consists out of only white spaces. + /// Numeric value field is not a number or too large/small to be represented as . + /// Variance value field is not a number or too large/small to be represented as . + /// Boolean field is not a valid value. + /// + private StructuresParameterRow CreateStructuresParameterRow(string readText) + { + string[] tokenizedText = TokenizeString(readText); + + // TODO: tokenizedText.Length smaller than largest index value => LineParseException + + string locationId = ParseLocationId(tokenizedText); + string parameterId = ParseParameterId(tokenizedText); + double numbericValue = ParseNumericValue(tokenizedText); + double varianceValue = ParseVarianceValue(tokenizedText); + VarianceType varianceType = ParseVarianceType(tokenizedText); + + return new StructuresParameterRow + { + LocationId = locationId, + ParameterId = parameterId, + NumericalValue = numbericValue, + VarianceValue = varianceValue, + VarianceType = varianceType + }; + } + + /// + /// Tokenizes a string using a separator character up to the first empty field. + /// + /// The text. + /// The tokenized parts. + /// lacks separator character. + private string[] TokenizeString(string readText) + { + if (!readText.Contains(separator)) + { + throw CreateLineParseException(lineNumber, string.Format("Regel ontbreekt het verwachte scheidingsteken (het karakter: {0}).", + separator)); + } + return readText.Split(separator) + .TakeWhile(text => !string.IsNullOrEmpty(text)) + .ToArray(); + } + + /// + /// Parses the location identifier from the read text. + /// + /// The tokenized text. + /// The location ID. + /// Location ID field is empty or only has whitespaces. + private string ParseLocationId(string[] tokenizedText) + { + string locationId = tokenizedText[locationIdIndex]; + if (string.IsNullOrWhiteSpace(locationId)) + { + throw CreateLineParseException(lineNumber, "'Identificatie' kolom mag geen lege waardes bevatten."); + } + return locationId; + } + + /// + /// Parses the parameter identifier from the read text. + /// + /// The tokenized text. + /// + /// The parameter ID. + /// Parameter ID field is empty or only has whitespaces. + private string ParseParameterId(string[] tokenizedText) + { + string parameterId = tokenizedText[parameterIdIndex]; + if (string.IsNullOrWhiteSpace(parameterId)) + { + throw CreateLineParseException(lineNumber, "'Kunstwerken.identificatie' kolom mag geen lege waardes bevatten."); + } + return parameterId; + } + + /// + /// Parses the numeric value. + /// + /// The tokenized text. + /// The numeric value (can be ). + /// When the numeric value field is not a number + /// or when it's too large or too small to be represented as . + private double ParseNumericValue(string[] tokenizedText) + { + string numericValueText = tokenizedText[numericValueIndex]; + return ParseDoubleValue(numericValueText, "Nummerieke waarde"); + } + + /// + /// Parses the standard deviation or coefficient of variation value. + /// + /// The tokenized text. + /// The standard deviation or coefficient of variation value (can be ). + /// When the standard deviation or coefficient + /// of variation value field is not a number or when it's too large or too small + /// to be represented as . + private double ParseVarianceValue(string[] tokenizedText) + { + string varianceValueText = tokenizedText[varianceValueIndex]; + return ParseDoubleValue(varianceValueText, "Variantie waarde"); + } + + /// + /// Parses the double value. + /// + /// The value text to be parsed. + /// Name of the parameter. + /// when is null + /// or only whitespaces; otherwise the parsed number. + /// When is + /// not a number or when it's too large or too small to be represented as . + private double ParseDoubleValue(string doubleValueText, string parameterName) + { + if (string.IsNullOrWhiteSpace(doubleValueText)) + { + return double.NaN; + } + try + { + return double.Parse(doubleValueText); + } + catch (FormatException e) + { + throw CreateLineParseException(lineNumber, string.Format("{0} kan niet worden omgezet naar een getal.", + parameterName), e); + } + catch (OverflowException e) + { + throw CreateLineParseException(lineNumber, string.Format("{0} is te groot of te klein om ingelezen te worden.", + parameterName), e); + } + } + + /// + /// Parses the value that indicates how the variance field should be interpreted. + /// + /// The tokenized text. + /// The based on the text in the file. + /// When the 'boolean' field is not a valid value. + private VarianceType ParseVarianceType(string[] tokenizedText) + { + string varianceTypeText = tokenizedText[varianceTypeIndex]; + if (string.IsNullOrWhiteSpace(varianceTypeText)) + { + return VarianceType.NotSpecified; + } + try + { + int typeValue = int.Parse(varianceTypeText); + if (typeValue == 0) + { + return VarianceType.CoefficientOfVariation; + } + if (typeValue == 1) + { + return VarianceType.StandardDeviation; + } + throw CreateLineParseException(lineNumber, "De 'Boolean' kolom mag uitsluitend de waardes '0' of '1' bevatten, of mag leeg zijn."); + } + catch (FormatException e) + { + throw CreateLineParseException(lineNumber, "De 'Boolean' kolom mag uitsluitend de waardes '0' of '1' bevatten, of mag leeg zijn.", e); + } + catch (OverflowException e) + { + throw CreateLineParseException(lineNumber, "De 'Boolean' kolom mag uitsluitend de waardes '0' of '1' bevatten, of mag leeg zijn.", 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 set. + private LineParseException CreateLineParseException(int currentLine, string lineParseErrorMessage, Exception innerException = null) + { + string locationDescription = string.Format(CoreCommonUtilsResources.TextFile_On_LineNumber_0_, currentLine); + var message = new FileReaderErrorMessageBuilder(filePath).WithLocation(locationDescription) + .Build(lineParseErrorMessage); + return new LineParseException(message, innerException); + } + + /// + /// 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(CoreCommonUtilsResources.TextFile_On_LineNumber_0_, + currentLine); + var message = new FileReaderErrorMessageBuilder(filePath).WithLocation(locationDescription) + .Build(criticalErrorMessage); + return new CriticalFileReadException(message, innerException); + } + } +} \ No newline at end of file Index: Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresParameterRow.cs =================================================================== diff -u -r60bd3c063c8173f762c5762096efa38b87f780ed -r653c18f73b4404d9ac58d818845474d68e48635d --- Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresParameterRow.cs (.../StructuresParameterRow.cs) (revision 60bd3c063c8173f762c5762096efa38b87f780ed) +++ Ringtoets/Common/src/Ringtoets.Common.IO/Structures/StructuresParameterRow.cs (.../StructuresParameterRow.cs) (revision 653c18f73b4404d9ac58d818845474d68e48635d) @@ -38,6 +38,11 @@ } /// + /// Gets or sets the location identifier to which this parameter belongs. + /// + public string LocationId { get; set; } + + /// /// Gets or sets the ID of this parameter. /// public string ParameterId { get; set; } Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj =================================================================== diff -u -r60bd3c063c8173f762c5762096efa38b87f780ed -r653c18f73b4404d9ac58d818845474d68e48635d --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj (.../Ringtoets.Common.IO.Test.csproj) (revision 60bd3c063c8173f762c5762096efa38b87f780ed) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Ringtoets.Common.IO.Test.csproj (.../Ringtoets.Common.IO.Test.csproj) (revision 653c18f73b4404d9ac58d818845474d68e48635d) @@ -68,7 +68,7 @@ - + Fisheye: Tag 653c18f73b4404d9ac58d818845474d68e48635d refers to a dead (removed) revision in file `Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/HeightStructuresCharacteristicsCsvReaderTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/StructuresCharacteristicsCsvReaderTest.cs =================================================================== diff -u --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/StructuresCharacteristicsCsvReaderTest.cs (revision 0) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/StructuresCharacteristicsCsvReaderTest.cs (revision 653c18f73b4404d9ac58d818845474d68e48635d) @@ -0,0 +1,152 @@ +// 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.IO.Exceptions; +using Core.Common.TestUtil; +using Core.Common.Utils.Builders; +using NUnit.Framework; +using Ringtoets.Common.IO.Structures; +using UtilsResources = Core.Common.Utils.Properties.Resources; + +namespace Ringtoets.Common.IO.Test.Structures +{ + [TestFixture] + public class StructuresCharacteristicsCsvReaderTest + { + private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.HeightStructures.IO, string.Format("Characteristics{0}", Path.DirectorySeparatorChar)); + + [Test] + [TestCase("")] + [TestCase(null)] + [TestCase(" ")] + public void Constructor_InvalidStringArgument_ThrowsArgumentException(string path) + { + // Call + TestDelegate call = () => new StructuresCharacteristicsCsvReader(path); + + // Assert + string expectedMessage = new FileReaderErrorMessageBuilder(path).Build(UtilsResources.Error_Path_must_be_specified); + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage); + } + + [Test] + public void Constructor_InvalidPathCharactersInPath_ThrowsArgumentException() + { + // Setup + string path = Path.Combine(testDataPath, "ValidCharacteristics.csv"); + + char[] invalidCharacters = Path.GetInvalidPathChars(); + + string corruptPath = path.Replace('V', invalidCharacters[0]); + + // Call + TestDelegate call = () => new StructuresCharacteristicsCsvReader(corruptPath); + + // Assert + string innerExpectedMessage = string.Format((string)UtilsResources.Error_Path_cannot_contain_Characters_0_, + string.Join(", ", Path.GetInvalidFileNameChars())); + string expectedMessage = new FileReaderErrorMessageBuilder(corruptPath).Build(innerExpectedMessage); + TestHelper.AssertThrowsArgumentExceptionAndTestMessage(call, expectedMessage); + } + + [Test] + public void Constructor_PathToFolder_ThrowsArgumentException() + { + // Call + TestDelegate call = () => new StructuresCharacteristicsCsvReader(testDataPath); + + // Assert + ArgumentException exception = Assert.Throws(call); + string expectedMessage = new FileReaderErrorMessageBuilder(testDataPath).Build(UtilsResources.Error_Path_must_not_point_to_empty_file_name); + Assert.AreEqual(expectedMessage, exception.Message); + } + + [Test] + public void GetLineCount_FileDoesNotExist_ThrowCriticalFileReadException() + { + // Setup + const string invalidFilePath = "I_do_not_exist.csv"; + + var reader = new StructuresCharacteristicsCsvReader(invalidFilePath); + + // Call + TestDelegate call = () => reader.GetLineCount(); + + // Assert + string message = Assert.Throws(call).Message; + Assert.AreEqual("Fout bij het lezen van bestand 'I_do_not_exist.csv': Het bestand bestaat niet.", message); + } + + [Test] + public void GetLineCount_FolderDoesNotExist_ThrowCriticalFileReadException() + { + // Setup + string invalidFilePath = Path.Combine("I_do_not_exist", "I do not exist either.csv"); + + var reader = new StructuresCharacteristicsCsvReader(invalidFilePath); + + // Call + TestDelegate call = () => reader.GetLineCount(); + + // Assert + string message = Assert.Throws(call).Message; + string expectedMessage = string.Format("Fout bij het lezen van bestand '{0}': Het bestandspad verwijst naar een map die niet bestaat.", + invalidFilePath); + Assert.AreEqual(expectedMessage, message); + } + + [Test] + public void ReadLine_FileDoesNotExist_ThrowCriticalFileReadException() + { + // Setup + const string invalidFilePath = "I_do_not_exist.csv"; + + var reader = new StructuresCharacteristicsCsvReader(invalidFilePath); + + // Call + TestDelegate call = () => reader.ReadLine(); + + // Assert + string message = Assert.Throws(call).Message; + Assert.AreEqual("Fout bij het lezen van bestand 'I_do_not_exist.csv': Het bestand bestaat niet.", message); + } + + [Test] + public void ReadLine_FolderDoesNotExist_ThrowCriticalFileReadException() + { + // Setup + string invalidFilePath = Path.Combine("I_do_not_exist", "I do not exist either.csv"); + + var reader = new StructuresCharacteristicsCsvReader(invalidFilePath); + + // Call + TestDelegate call = () => reader.ReadLine(); + + // Assert + string message = Assert.Throws(call).Message; + string expectedMessage = string.Format("Fout bij het lezen van bestand '{0}': Het bestandspad verwijst naar een map die niet bestaat.", + invalidFilePath); + Assert.AreEqual(expectedMessage, message); + } + } +} \ No newline at end of file Index: Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/StructuresParameterRowTest.cs =================================================================== diff -u -r60bd3c063c8173f762c5762096efa38b87f780ed -r653c18f73b4404d9ac58d818845474d68e48635d --- Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/StructuresParameterRowTest.cs (.../StructuresParameterRowTest.cs) (revision 60bd3c063c8173f762c5762096efa38b87f780ed) +++ Ringtoets/Common/test/Ringtoets.Common.IO.Test/Structures/StructuresParameterRowTest.cs (.../StructuresParameterRowTest.cs) (revision 653c18f73b4404d9ac58d818845474d68e48635d) @@ -34,6 +34,7 @@ var parameter = new StructuresParameterRow(); // Assert + Assert.IsNull(parameter.LocationId); Assert.IsNull(parameter.ParameterId); Assert.IsNaN(parameter.NumericalValue); Assert.IsNaN(parameter.VarianceValue); @@ -42,21 +43,23 @@ } [Test] - [TestCase("A", 1.1, -2.2, VarianceType.CoefficientOfVariation, 4)] - [TestCase("B", -3.3, 4.4, VarianceType.StandardDeviation, 96758)] - public void SimpleProperties_SetNewValues_GetNewlySetValues(string id, double numerical, double variance, VarianceType type, int lineNumber) + [TestCase("1", "A", 1.1, -2.2, VarianceType.CoefficientOfVariation, 4)] + [TestCase("2", "B", -3.3, 4.4, VarianceType.StandardDeviation, 96758)] + public void SimpleProperties_SetNewValues_GetNewlySetValues(string locationId, string id, double numerical, double variance, VarianceType type, int lineNumber) { // Setup var parameter = new StructuresParameterRow(); // Call + parameter.LocationId = locationId; parameter.ParameterId = id; parameter.NumericalValue = numerical; parameter.VarianceValue = variance; parameter.VarianceType = type; parameter.LineNumber = lineNumber; // Assert + Assert.AreEqual(locationId, parameter.LocationId); Assert.AreEqual(id, parameter.ParameterId); Assert.AreEqual(numerical, parameter.NumericalValue); Assert.AreEqual(variance, parameter.VarianceValue);