Index: src/Plugins/Wti/Wti.Data/PipingSurfaceLine.cs =================================================================== diff -u -rb08cd825acc24d8d7b0f5e802bf65efece7ee4be -rc42d0c47753135357002db6026ebbefc3603a62b --- src/Plugins/Wti/Wti.Data/PipingSurfaceLine.cs (.../PipingSurfaceLine.cs) (revision b08cd825acc24d8d7b0f5e802bf65efece7ee4be) +++ src/Plugins/Wti/Wti.Data/PipingSurfaceLine.cs (.../PipingSurfaceLine.cs) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -1,7 +1,56 @@ -namespace Wti.Data +using System.Collections.Generic; +using System.Linq; + +namespace Wti.Data { + /// + /// Definition of a surfaceline for piping. + /// public class PipingSurfaceLine { - + /// + /// Initializes a new instance of the class. + /// + public PipingSurfaceLine() + { + Name = string.Empty; + Points = Enumerable.Empty(); + } + + /// + /// Gets or sets the name of the surfaceline. + /// + public string Name { get; set; } + + /// + /// Gets or sets the 3D points describing its geometry. + /// + public IEnumerable Points { get; private set; } + + /// + /// Gets or sets the first 3D geometry point defining the surfaceline in world coordinates. + /// + public Point3D StartingWorldPoint { get; private set; } + + /// + /// Gets or sets the last 3D geometry point defining the surfaceline in world coordinates. + /// + public Point3D EndingWorldPoint { get; private set; } + + /// + /// Sets the geometry of the surfaceline. + /// + /// The collection of points defining the surfaceline geometry. + public void SetGeometry(IEnumerable points) + { + var point3Ds = points.ToArray(); + Points = point3Ds; + + if (point3Ds.Length > 0) + { + StartingWorldPoint = point3Ds[0]; + EndingWorldPoint = point3Ds[point3Ds.Length - 1]; + } + } } } \ No newline at end of file Index: src/Plugins/Wti/Wti.Data/Point3D.cs =================================================================== diff -u --- src/Plugins/Wti/Wti.Data/Point3D.cs (revision 0) +++ src/Plugins/Wti/Wti.Data/Point3D.cs (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,23 @@ +namespace Wti.Data +{ + /// + /// Defines a mathematical point in 3D Euclidean space. + /// + public class Point3D + { + /// + /// Gets or sets the x coordinate. + /// + public double X { get; set; } + + /// + /// Gets or sets the y coordinate. + /// + public double Y { get; set; } + + /// + /// Gets or sets the z coordinate. + /// + public double Z { get; set; } + } +} \ No newline at end of file Index: src/Plugins/Wti/Wti.Data/Wti.Data.csproj =================================================================== diff -u -r7311da16a34bc2588440d0166f3a09402e4fd16f -rc42d0c47753135357002db6026ebbefc3603a62b --- src/Plugins/Wti/Wti.Data/Wti.Data.csproj (.../Wti.Data.csproj) (revision 7311da16a34bc2588440d0166f3a09402e4fd16f) +++ src/Plugins/Wti/Wti.Data/Wti.Data.csproj (.../Wti.Data.csproj) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -45,6 +45,7 @@ + Index: src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs =================================================================== diff -u -rbb61ed227cf79e994b84019096e4297b2fbd4527 -rc42d0c47753135357002db6026ebbefc3603a62b --- src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision bb61ed227cf79e994b84019096e4297b2fbd4527) +++ src/Plugins/Wti/Wti.IO/PipingSurfaceLinesCsvReader.cs (.../PipingSurfaceLinesCsvReader.cs) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -1,5 +1,11 @@ using System; +using System.Globalization; +using System.IO; +using System.Linq; +using Wti.Data; +using Wti.IO.Properties; + namespace Wti.IO { /// @@ -10,8 +16,108 @@ /// Where {ID} has to be a particular accepted text, and n triplets of doubles form the /// 3D coordinates defining the geometric shape of the surfaceline.. /// - public class PipingSurfaceLinesCsvReader + public class PipingSurfaceLinesCsvReader : IDisposable { private readonly string[] acceptableIdNames = { "Profielnaam, LocationID" }; + private readonly string filePath; + private StreamReader fileReader; + + /// + /// Initializes a new instance of the class + /// and opens a given file path. + /// + /// The path to the file to be read. + public PipingSurfaceLinesCsvReader(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + throw new ArgumentException(Resources.Error_PathMustBeSpecified); + } + filePath = path; + } + + public void Dispose() + { + if (fileReader != null) + { + fileReader.Dispose(); + fileReader = null; + } + } + + /// + /// Reads the file to determine the number of available + /// data rows. + /// + /// A value greater than or equal to 0. + /// The file cannot be found. + /// The specified path is invalid, such as being on an unmapped drive. + /// Filepath 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. + public int GetSurfaceLinesCount() + { + var count = 0; + using (var reader = new StreamReader(filePath)) + { + // Skip header: + reader.ReadLine(); + + // Count SurfaceLines: + string line; + while ((line = reader.ReadLine()) != null) + { + if (!String.IsNullOrWhiteSpace(line)) + { + count++; + } + } + } + return count; + } + + /// + /// Reads and consumes the next data row, parsing the data to create an instance + /// of . + /// + /// Return the parse surfaceline, or null when at the end of the file. + /// The file cannot be found. + /// The specified path is invalid, such as being on an unmapped drive. + /// Filepath 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. + public PipingSurfaceLine ReadLine() + { + if (fileReader == null) + { + fileReader = new StreamReader(filePath); + // Skip Header: + fileReader.ReadLine(); + } + var readText = fileReader.ReadLine(); + if (readText != null) + { + var tokenizedString = readText.Split(';'); + var worldCoordinateValues = tokenizedString.Skip(1) + .Select(ts => Double.Parse(ts, CultureInfo.InvariantCulture)) + .ToArray(); + int coordinateCount = worldCoordinateValues.Length/3; + var points = new Point3D[coordinateCount]; + for (int i = 0; i < coordinateCount; i++) + { + points[i] = new Point3D + { + X = worldCoordinateValues[i*3], + Y = worldCoordinateValues[i*3+1], + Z = worldCoordinateValues[i*3+2] + }; + } + + var surfaceLine = new PipingSurfaceLine(); + surfaceLine.Name = tokenizedString.First(); + surfaceLine.SetGeometry(points); + return surfaceLine; + } + + return null; + } } } \ No newline at end of file Index: src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs =================================================================== diff -u --- src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs (revision 0) +++ src/Plugins/Wti/Wti.IO/Properties/Resources.Designer.cs (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Wti.IO.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Wti.IO.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Bestandspad mag niet leeg of ongedefinieerd zijn.. + /// + internal static string Error_PathMustBeSpecified { + get { + return ResourceManager.GetString("Error_PathMustBeSpecified", resourceCulture); + } + } + } +} Index: src/Plugins/Wti/Wti.IO/Properties/Resources.resx =================================================================== diff -u --- src/Plugins/Wti/Wti.IO/Properties/Resources.resx (revision 0) +++ src/Plugins/Wti/Wti.IO/Properties/Resources.resx (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Bestandspad mag niet leeg of ongedefinieerd zijn. + + \ No newline at end of file Index: src/Plugins/Wti/Wti.IO/Wti.IO.csproj =================================================================== diff -u -r7311da16a34bc2588440d0166f3a09402e4fd16f -rc42d0c47753135357002db6026ebbefc3603a62b --- src/Plugins/Wti/Wti.IO/Wti.IO.csproj (.../Wti.IO.csproj) (revision 7311da16a34bc2588440d0166f3a09402e4fd16f) +++ src/Plugins/Wti/Wti.IO/Wti.IO.csproj (.../Wti.IO.csproj) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -44,6 +44,11 @@ + + True + True + Resources.resx + @@ -60,6 +65,12 @@ Wti.Data + + + ResXFileCodeGenerator + Resources.Designer.cs + + Index: test-data/Plugins/Wti/IO/PipingSurfaceLinesCsvReader/TwoValidSurfaceLines.csv =================================================================== diff -u --- test-data/Plugins/Wti/IO/PipingSurfaceLinesCsvReader/TwoValidSurfaceLines.csv (revision 0) +++ test-data/Plugins/Wti/IO/PipingSurfaceLinesCsvReader/TwoValidSurfaceLines.csv (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,3 @@ +Profielnaam;X1;Y1;Z1...;Xn;Yn;Zn +Rotterdam1;94263.0026213;427776.654093;-1.02;94275.9126686;427811.080886;-1.04;94284.0663827;427831.918156;1.25;94294.9380015;427858.191234;1.45;94305.3566362;427889.900123;1.65;94315.0957947;427913.908281;1.66;94325.0614453;427941.766804;1.55;94331.1767309;427960.112661;1.44 +ArtificalLocal;2.3;0;1.0;5.7;0;2.0;4.4;0;1.1 \ No newline at end of file Index: test-data/Plugins/Wti/IO/PipingSurfaceLinesCsvReader/ValidFileWithoutSurfaceLines.csv =================================================================== diff -u --- test-data/Plugins/Wti/IO/PipingSurfaceLinesCsvReader/ValidFileWithoutSurfaceLines.csv (revision 0) +++ test-data/Plugins/Wti/IO/PipingSurfaceLinesCsvReader/ValidFileWithoutSurfaceLines.csv (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,2 @@ +Profielnaam;X1;Y1;Z1...;Xn;Yn;Zn + Index: test/Common/DelftTools.TestUtils/TestDataPath.cs =================================================================== diff -u -rdbf346f0cc265bf639c1b94ac0eedc1c7bd9d0e4 -rc42d0c47753135357002db6026ebbefc3603a62b --- test/Common/DelftTools.TestUtils/TestDataPath.cs (.../TestDataPath.cs) (revision dbf346f0cc265bf639c1b94ac0eedc1c7bd9d0e4) +++ test/Common/DelftTools.TestUtils/TestDataPath.cs (.../TestDataPath.cs) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -37,5 +37,13 @@ public static readonly TestDataPath DeltaShellDeltaShellPluginsSharpMapGisTestsRasterData = @"DeltaShell/DeltaShell.Plugins.SharpMapGis.Tests/RasterData/"; } + + public static class Plugins + { + public static class Wti + { + public static readonly TestDataPath WtiIOPath = @"Plugins/Wti/IO/"; + } + } } } \ No newline at end of file Index: test/Plugins/Wti/Wti.Data.Test/PipingSurfaceLineTest.cs =================================================================== diff -u --- test/Plugins/Wti/Wti.Data.Test/PipingSurfaceLineTest.cs (revision 0) +++ test/Plugins/Wti/Wti.Data.Test/PipingSurfaceLineTest.cs (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,59 @@ +using System; +using System.Linq; + +using NUnit.Framework; + +namespace Wti.Data.Test +{ + [TestFixture] + public class PipingSurfaceLineTest + { + [Test] + public void DefaultConstructor_ExpectedValues() + { + // Call + var surfaceLine = new PipingSurfaceLine(); + + // Assert + Assert.AreEqual(String.Empty, surfaceLine.Name); + CollectionAssert.IsEmpty(surfaceLine.Points); + Assert.IsNull(surfaceLine.StartingWorldPoint); + Assert.IsNull(surfaceLine.EndingWorldPoint); + } + + [Test] + public void SetGeometry_EmptyCollection_PointsSetEmptyAndNullStartAndEndWorldPoints() + { + // Setup + var surfaceLine = new PipingSurfaceLine(); + + var sourceData = Enumerable.Empty(); + + // Call + surfaceLine.SetGeometry(sourceData); + + // Assert + CollectionAssert.IsEmpty(surfaceLine.Points); + Assert.IsNull(surfaceLine.StartingWorldPoint); + Assert.IsNull(surfaceLine.EndingWorldPoint); + } + + [Test] + public void SetGeometry_CollectionOfOnePoint_InitializeStartAndEndWorldPointsToSameInstanceAndInitializePoints() + { + // Setup + var surfaceLine = new PipingSurfaceLine(); + + var sourceData = new[]{new Point3D{X=1.1,Y=2.2,Z=3.3}}; + + // Call + surfaceLine.SetGeometry(sourceData); + + // Assert + Assert.AreNotSame(sourceData, surfaceLine.Points); + CollectionAssert.AreEqual(sourceData, surfaceLine.Points); + Assert.AreSame(sourceData[0], surfaceLine.StartingWorldPoint); + Assert.AreSame(sourceData[0], surfaceLine.EndingWorldPoint); + } + } +} \ No newline at end of file Index: test/Plugins/Wti/Wti.Data.Test/Point3DTest.cs =================================================================== diff -u --- test/Plugins/Wti/Wti.Data.Test/Point3DTest.cs (revision 0) +++ test/Plugins/Wti/Wti.Data.Test/Point3DTest.cs (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -0,0 +1,37 @@ +using NUnit.Framework; + +namespace Wti.Data.Test +{ + [TestFixture] + public class Point3DTest + { + [Test] + public void DefaultConstructor_ExpectedValues() + { + // Call + var point = new Point3D(); + + // Assert + Assert.AreEqual(0, point.X); + Assert.AreEqual(0, point.Y); + Assert.AreEqual(0, point.Z); + } + + [Test] + public void AutomaticProperties_SetAndGetValuesAgain_ReturnedValueShouldBeSameAsSetValue() + { + // Setup + var point = new Point3D(); + + // Call + point.X = 1.1; + point.Y = 2.2; + point.Z = -1.1; + + // Assert + Assert.AreEqual(1.1, point.X); + Assert.AreEqual(2.2, point.Y); + Assert.AreEqual(-1.1, point.Z); + } + } +} \ No newline at end of file Index: test/Plugins/Wti/Wti.Data.Test/Wti.Data.Test.csproj =================================================================== diff -u -rb08cd825acc24d8d7b0f5e802bf65efece7ee4be -rc42d0c47753135357002db6026ebbefc3603a62b --- test/Plugins/Wti/Wti.Data.Test/Wti.Data.Test.csproj (.../Wti.Data.Test.csproj) (revision b08cd825acc24d8d7b0f5e802bf65efece7ee4be) +++ test/Plugins/Wti/Wti.Data.Test/Wti.Data.Test.csproj (.../Wti.Data.Test.csproj) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -49,6 +49,8 @@ + + Index: test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs =================================================================== diff -u -rbb61ed227cf79e994b84019096e4297b2fbd4527 -rc42d0c47753135357002db6026ebbefc3603a62b --- test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs (.../PipingSurfaceLinesCsvReaderTest.cs) (revision bb61ed227cf79e994b84019096e4297b2fbd4527) +++ test/Plugins/Wti/Wti.IO.Test/PipingSurfaceLinesCsvReaderTest.cs (.../PipingSurfaceLinesCsvReaderTest.cs) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -1,10 +1,160 @@ -using NUnit.Framework; +using System; +using System.IO; +using System.Linq; +using DelftTools.TestUtils; + +using NUnit.Framework; + namespace Wti.IO.Test { [TestFixture] public class PipingSurfaceLinesCsvReaderTest { - + private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Plugins.Wti.WtiIOPath, "PipingSurfaceLinesCsvReader"); + + [Test] + [TestCase("")] + [TestCase(null)] + [TestCase(" ")] + public void ParameterdConstructor_InvalidStringArgument_ArgumentException(string path) + { + // Call + TestDelegate call = () => new PipingSurfaceLinesCsvReader(path); + + // Assert + var exception = Assert.Throws(call); + Assert.AreEqual("Bestandspad mag niet leeg of ongedefinieerd zijn.", exception.Message); + } + + [Test] + public void ParameterdConstructor_AnyPath_ExpectedValues() + { + // Setup + const string fakeFilePath = @"I\Dont\Really\Exist"; + + // Call + using (var reader = new PipingSurfaceLinesCsvReader(fakeFilePath)) + { + // Assert + Assert.IsInstanceOf(reader); + } + } + + [Test] + public void GetLineCount_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnNumberOfSurfaceLines() + { + // Setup + string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv"); + + using (var reader = new PipingSurfaceLinesCsvReader(path)) + { + // Call + int linesCount = reader.GetSurfaceLinesCount(); + + // Assert + Assert.AreEqual(2, linesCount); + } + } + + [Test] + public void GetLineCount_OpenedValidFileWithHeaderAndNoSurfaceLines_ReturnZero() + { + // Setup + string path = Path.Combine(testDataPath, "ValidFileWithoutSurfaceLines.csv"); + + using (var reader = new PipingSurfaceLinesCsvReader(path)) + { + // Call + int linesCount = reader.GetSurfaceLinesCount(); + + // Assert + Assert.AreEqual(0, linesCount); + } + } + + [Test] + [SetCulture("nl-NL")] + public void ReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLinesWithCultureNL_ReturnCreatedSurfaceLine() + { + DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine(); + } + + [Test] + [SetCulture("en-US")] + public void ReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLinesWithCultureEN_ReturnCreatedSurfaceLine() + { + DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine(); + } + + private void DoReadLine_OpenedValidFileWithHeaderAndTwoSurfaceLines_ReturnCreatedSurfaceLine() + { + // Setup + string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv"); + + using (var reader = new PipingSurfaceLinesCsvReader(path)) + { + // Call + var surfaceLine1 = reader.ReadLine(); + var surfaceLine2 = reader.ReadLine(); + + // Assert + + #region 1st surfaceline + + Assert.AreEqual("Rotterdam1", surfaceLine1.Name); + Assert.AreEqual(8, surfaceLine1.Points.Count()); + Assert.AreEqual(94263.0026213, surfaceLine1.StartingWorldPoint.X); + Assert.AreEqual(427776.654093, surfaceLine1.StartingWorldPoint.Y); + Assert.AreEqual(-1.02, surfaceLine1.StartingWorldPoint.Z); + Assert.AreEqual(94331.1767309, surfaceLine1.EndingWorldPoint.X); + Assert.AreEqual(427960.112661, surfaceLine1.EndingWorldPoint.Y); + Assert.AreEqual(1.44, surfaceLine1.EndingWorldPoint.Z); + Assert.AreEqual(surfaceLine1.StartingWorldPoint, surfaceLine1.Points.First()); + Assert.AreEqual(surfaceLine1.EndingWorldPoint, surfaceLine1.Points.Last()); + + #endregion + + #region 2nd surfaceline + + Assert.AreEqual("ArtificalLocal", surfaceLine2.Name); + Assert.AreEqual(3, surfaceLine2.Points.Count()); + Assert.AreEqual(2.3, surfaceLine2.StartingWorldPoint.X); + Assert.AreEqual(0, surfaceLine2.StartingWorldPoint.Y); + Assert.AreEqual(1, surfaceLine2.StartingWorldPoint.Z); + Assert.AreEqual(4.4, surfaceLine2.EndingWorldPoint.X); + Assert.AreEqual(0, surfaceLine2.EndingWorldPoint.Y); + Assert.AreEqual(1.1, surfaceLine2.EndingWorldPoint.Z); + Assert.AreEqual(surfaceLine2.StartingWorldPoint, surfaceLine2.Points.First()); + Assert.AreEqual(surfaceLine2.EndingWorldPoint, surfaceLine2.Points.Last()); + + #endregion + } + } + + [Test] + public void ReadLine_OpenedValidFileWithoutHeaderAndTwoSurfaceLinesWhileAtTheEndOfFile_ReturnNull() + { + // Setup + string path = Path.Combine(testDataPath, "TwoValidSurfaceLines.csv"); + + using (var reader = new PipingSurfaceLinesCsvReader(path)) + { + int surfaceLinesCount = reader.GetSurfaceLinesCount(); + for (int i = 0; i < surfaceLinesCount; i++) + { + var pipingSurfaceLine = reader.ReadLine(); + Assert.IsNotInstanceOf(pipingSurfaceLine, + "Fail Fast: Disposal logic required to be implemented in test."); + Assert.IsNotNull(pipingSurfaceLine); + } + + // Call + var result = reader.ReadLine(); + + // Assert + Assert.IsNull(result); + } + } } } \ No newline at end of file Index: test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj =================================================================== diff -u -rbb61ed227cf79e994b84019096e4297b2fbd4527 -rc42d0c47753135357002db6026ebbefc3603a62b --- test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj (.../Wti.IO.Test.csproj) (revision bb61ed227cf79e994b84019096e4297b2fbd4527) +++ test/Plugins/Wti/Wti.IO.Test/Wti.IO.Test.csproj (.../Wti.IO.Test.csproj) (revision c42d0c47753135357002db6026ebbefc3603a62b) @@ -50,6 +50,10 @@ {35b87b7a-7f50-4139-b563-589ee522b1ed} Wti.IO + + {EFA25023-CF6A-4FF7-8C42-B24D7F9509E1} + DelftTools.TestUtils +