Skip to content

Commit

Permalink
[PoC]
Browse files Browse the repository at this point in the history
  • Loading branch information
eduherminio committed Dec 2, 2023
1 parent 6a3b2aa commit a723e1a
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 8 deletions.
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.")]

Check warning on line 219 in src/FileParser/Implementations/ParsedFile.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Do not forget to remove this deprecated code someday. (https://rules.sonarsource.com/csharp/RSPEC-1133)
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

Check warning on line 237 in src/FileParser/Implementations/ParsedFile.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Complete the task associated to this 'TODO' comment. (https://rules.sonarsource.com/csharp/RSPEC-1135)

Check warning on line 237 in src/FileParser/Implementations/ParsedFile.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Complete the task associated to this 'TODO' comment. (https://rules.sonarsource.com/csharp/RSPEC-1135)

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); // Probably not needed, but just in case
}

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

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Possible null reference return.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (macOS-latest)

Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (macOS-latest)

Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (macOS-latest)

Possible null reference return.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI linux)

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,27): Error CS8600: Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI linux)

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,24): Error CS8600: Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI linux)

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,24): Error CS8603: Possible null reference return.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI mac)

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,27): Error CS8600: Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI mac)

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,24): Error CS8600: Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI mac)

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,24): Error CS8603: Possible null reference return.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,27): Error CS8600: Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,24): Error CS8600: Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser

src/FileParser/Utils/StringConverter.cs#L19

src/FileParser/Utils/StringConverter.cs(19,24): Error CS8603: Possible null reference return.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Converting null literal or possible null value to non-nullable type.

Check failure on line 19 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Possible null reference return.
}
return default(T) switch
{
short => (T)(object)short.Parse(str),

Check failure on line 23 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Possible null reference argument for parameter 's' in 'short short.Parse(string s)'.

Check failure on line 23 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (macOS-latest)

Possible null reference argument for parameter 's' in 'short short.Parse(string s)'.

Check failure on line 23 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI linux)

src/FileParser/Utils/StringConverter.cs#L23

src/FileParser/Utils/StringConverter.cs(23,49): Error CS8604: Possible null reference argument for parameter 's' in 'short short.Parse(string s)'.

Check failure on line 23 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser (CI CI mac)

src/FileParser/Utils/StringConverter.cs#L23

src/FileParser/Utils/StringConverter.cs(23,49): Error CS8604: Possible null reference argument for parameter 's' in 'short short.Parse(string s)'.

Check failure on line 23 in src/FileParser/Utils/StringConverter.cs

View check run for this annotation

Azure Pipelines / eduherminio.FileParser

src/FileParser/Utils/StringConverter.cs#L23

src/FileParser/Utils/StringConverter.cs(23,49): Error CS8604: Possible null reference argument for parameter 's' in 'short short.Parse(string s)'.

Check failure on line 23 in src/FileParser/Utils/StringConverter.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Possible null reference argument for parameter 's' in 'short short.Parse(string s)'.
Expand Down
108 changes: 108 additions & 0 deletions tests/FileParser.Test/ParsedFileTest/ExtractTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,113 @@ 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,BirtDate,Score";
const string line4 = "Abraham,10,12/12/1990,9.05";

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]);
}
}
}

0 comments on commit a723e1a

Please sign in to comment.