Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions src/FileParser/Implementations/ParsedFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public ParsedFile(Queue<IParsedLine> parsedFile)
/// </summary>
/// <param name="path">FilePath</param>
/// <param name="existingSeparator">Word separator (space by default)</param>
public ParsedFile(string path, char[] existingSeparator)
: this(path, new string(existingSeparator))
/// <param name="ignoreEmptyItems"></param>
public ParsedFile(string path, char[] existingSeparator, bool ignoreEmptyItems = true)
: this(path, new string(existingSeparator), ignoreEmptyItems)
{
}

Expand All @@ -41,9 +42,10 @@ public ParsedFile(string path, char[] existingSeparator)
/// </summary>
/// <param name="path">FilePath</param>
/// <param name="existingSeparator">Word separator (space by default)</param>
public ParsedFile(string path, string? existingSeparator = null)
/// <param name="ignoreEmptyItems"></param>
public ParsedFile(string path, string? existingSeparator = null, bool ignoreEmptyItems = true)
#pragma warning disable CS0618 // Type or member is obsolete - will keep it as private
: base(ParseFile(path, existingSeparator))
: base(ParseFile(path, existingSeparator, ignoreEmptyItems))
#pragma warning restore CS0618 // Type or member is obsolete
{
}
Expand Down Expand Up @@ -207,14 +209,15 @@ public static List<List<T>> ReadAllGroupsOfLines<T>(string path)
/// </summary>
/// <param name="path"></param>
/// <param name="existingSeparator">Word separator</param>
/// <param name="ignoreEmptyItems"></param>
/// <exception cref="FileNotFoundException"></exception>
/// <exception cref="DirectoryNotFoundException"></exception>
/// <exception cref="IOException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
[Obsolete("This method exposes internal functionality and was made public accidentally. It will be removed in next major release, please used ParsedFile constructor instead.")]
public static Queue<IParsedLine> ParseFile(string path, string? existingSeparator = null)
public static Queue<IParsedLine> ParseFile(string path, string? existingSeparator = null, bool ignoreEmptyItems = true)
{
Queue<IParsedLine> parsedFile = new();

Expand All @@ -233,7 +236,7 @@ public static Queue<IParsedLine> ParseFile(string path, string? existingSeparato
}
// end TODO

IParsedLine parsedLine = new ParsedLine(ProcessLine(original_line, existingSeparator));
IParsedLine parsedLine = new ParsedLine(ProcessLine(original_line, existingSeparator, ignoreEmptyItems));
parsedFile.Enqueue(parsedLine);
}
}
Expand All @@ -248,13 +251,16 @@ public static Queue<IParsedLine> ParseFile(string path, string? existingSeparato
}
}

private static ICollection<string> ProcessLine(string original_line, string? separator)
private static ICollection<string> ProcessLine(string original_line, string? separator, bool ignoreEmptyItems)
{
List<string> wordsInLine = original_line
.Split(separator?.ToCharArray())
.Select(str => str.Trim()).ToList();

wordsInLine.RemoveAll(string.IsNullOrWhiteSpace); // Probably not needed, but just in case
if (ignoreEmptyItems)
{
wordsInLine.RemoveAll(string.IsNullOrWhiteSpace);
}

return wordsInLine;
}
Expand Down
5 changes: 5 additions & 0 deletions src/FileParser/Utils/StringConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ internal static class StringConverter
/// <returns></returns>
public static T Convert<T>(string str, TypeConverter? typeConverter = null)
{
if (str.Length == 0)
{
return default!;
}

return default(T) switch
{
short => (T)(object)short.Parse(str),
Expand Down
113 changes: 113 additions & 0 deletions tests/FileParser.Test/ParsedFileTest/ExtractTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,118 @@ public void ExtractChar()

Assert.Equal(line1 + '\\' + line2 + '\\', parsedFile.ToString());
}

[Fact]
public void MultipleCharWordSeparator()
{
const string fileName = "MultipleCharWordSeparator.txt";
const string line1 = " FirstName|| LastName ||Age||EyeColor ";
const string line2 = " John|| Doe||66 || Brown";

var expectedFirstLine = new[] { "FirstName", "LastName", "Age", "EyeColor" };
var expectedSecondLine = new[] { "John", "Doe", "66", "Brown" };

using (StreamWriter writer = new(fileName))
{
writer.WriteLine(line1);
writer.WriteLine(line2);
}

IParsedFile file = new ParsedFile(fileName, "||");

int index = 0;
var line = file.NextLine();
while (!line.Empty)
{
var item = line.NextElement<string>();
Assert.Equal(expectedFirstLine[index++], item);
}

line = file.NextLine();
Assert.Equal(expectedSecondLine, line.ToList<string>());

Assert.True(file.Empty);
}

[Fact]
public void ParseCsvFileIntoStrings()
{
const string fileName = "ParseCsvFileIntoStrings.txt";
const string line1 = "FirstName,LastName,Age,EyeColor";
const string line2 = "John,Doe,66,Brown";
const string line3 = "Cthulhu,,1000,Black";
const string line4 = "Bugs,Bunny,33,White";

using (StreamWriter writer = new(fileName))
{
writer.WriteLine(line1);
writer.WriteLine(line2);
writer.WriteLine(line3);
writer.WriteLine(line4);
}

IParsedFile file = new ParsedFile(fileName, ",", ignoreEmptyItems: false);

var headerLine = file.NextLine();
var buckets = new List<List<string>>(headerLine.ToList<string>().Select(header => new List<string>(1000) { ModifyString(header) }));

while (!file.Empty)
{
var line = file.NextLine().ToList<string>();
for (int index = 0; index < line.Count; ++index)
{
buckets[index].Add(ModifyString(line[index]));
}
}

static string ModifyString(string str) => str.ToLowerInvariant();

Assert.Equal(new[] { "firstname", "john", "cthulhu", "bugs" }, buckets[0]);
Assert.Equal(new[] { "lastname", "doe", "", "bunny" }, buckets[1]);
Assert.Equal(new[] { "age", "66", "1000", "33" }, buckets[2]);
Assert.Equal(new[] { "eyecolor", "brown", "black", "white" }, buckets[3]);
}

[Fact]
public void ParseCsvFile()
{
const string fileName = "ParseCsvFile.txt";
const string line1 = "Name,Age,Score";
const string line2 = "Abraham,10,9.05";
const string line3 = "Babilon,,64.05";
const string line4 = "Croc,99,";

using (StreamWriter writer = new(fileName))
{
writer.WriteLine(line1);
writer.WriteLine(line2);
writer.WriteLine(line3);
writer.WriteLine(line4);
}

IParsedFile file = new ParsedFile(fileName, ",", ignoreEmptyItems: false);

file.NextLine();

var line = file.NextLine();

Assert.Equal("Abraham", line.NextElement<string>());
Assert.Equal(10, line.NextElement<int>());
Assert.Equal(9.05, line.NextElement<double>());

line = file.NextLine();

Assert.Equal("Babilon", line.NextElement<string>());
Assert.Equal(default, line.NextElement<int>());
Assert.Equal(64.05, line.NextElement<double>());

line = file.NextLine();

Assert.Equal("Croc", line.NextElement<string>());
Assert.Equal(99, line.NextElement<int>());
Assert.Equal(default, line.NextElement<double>());

Assert.True(file.Empty);
}
}
}