Refactor event occurrence parsing by introducing modular components for improved maintainability
This commit restructures the EventOccurrenceParser by breaking down its functionality into modular components, including EventDefinitionResolver, LineClassifier, LocationPatternMatcher, SectionHeaderMatcher, TimeLocationParser, and TimeParser. This refactoring enhances code readability and maintainability, allowing for easier updates and testing. Additionally, the TextUtil class has been updated to include input sanitization methods. Comprehensive unit tests have been added to ensure the correctness of the new parsing logic and to validate the handling of various event occurrence scenarios.
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
using Core.Models;
|
||||
using Core.Parsers.EventOccurrence;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Tests.Parsers.EventOccurrence;
|
||||
|
||||
[TestFixture]
|
||||
public class TimeLocationParser_Tests
|
||||
{
|
||||
[Test]
|
||||
public void Parse_TimeAndLocation_ExtractsBoth()
|
||||
{
|
||||
// Arrange
|
||||
var locationConfig = new LocationParsingConfiguration
|
||||
{
|
||||
LocationPatterns = new List<string> { "Room *" }
|
||||
};
|
||||
|
||||
// Act
|
||||
TimeLocationParser.Parse("10:30 a.m. Room 101", locationConfig,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("10:30 a.m."));
|
||||
Assert.That(location, Is.EqualTo("Room 101"));
|
||||
Assert.That(locationParseSuccess, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parse_TimeRangeAndLocation_ExtractsTimeRangeAndLocation()
|
||||
{
|
||||
// Arrange
|
||||
var locationConfig = new LocationParsingConfiguration
|
||||
{
|
||||
LocationPatterns = new List<string> { "Room *" }
|
||||
};
|
||||
|
||||
// Act
|
||||
TimeLocationParser.Parse("10:00 a.m. - 12:00 p.m. Room 202", locationConfig,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("10:00 a.m. - 12:00 p.m."));
|
||||
Assert.That(location, Is.EqualTo("Room 202"));
|
||||
Assert.That(locationParseSuccess, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parse_NOONAndLocation_ExtractsBoth()
|
||||
{
|
||||
// Arrange
|
||||
var locationConfig = new LocationParsingConfiguration
|
||||
{
|
||||
LocationPatterns = new List<string> { "Hall *" }
|
||||
};
|
||||
|
||||
// Act
|
||||
TimeLocationParser.Parse("NOON Hall C", locationConfig,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("NOON"));
|
||||
Assert.That(location, Is.EqualTo("Hall C"));
|
||||
Assert.That(locationParseSuccess, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parse_TimeOnly_NoLocation()
|
||||
{
|
||||
// Arrange
|
||||
var locationConfig = new LocationParsingConfiguration
|
||||
{
|
||||
LocationPatterns = new List<string> { "Room *" }
|
||||
};
|
||||
|
||||
// Act
|
||||
TimeLocationParser.Parse("3:00 p.m.", locationConfig,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("3:00 p.m."));
|
||||
Assert.That(location, Is.Empty);
|
||||
Assert.That(locationParseSuccess, Is.True); // No location is valid
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parse_LocationNotMatchingPattern_StillReturnsLocation_ReportsFailure()
|
||||
{
|
||||
// Arrange
|
||||
var locationConfig = new LocationParsingConfiguration
|
||||
{
|
||||
LocationPatterns = new List<string> { "Room *" }
|
||||
};
|
||||
|
||||
// Act
|
||||
TimeLocationParser.Parse("10:00 a.m. Unknown Location", locationConfig,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("10:00 a.m."));
|
||||
Assert.That(location, Is.EqualTo("Unknown Location"));
|
||||
Assert.That(locationParseSuccess, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parse_LocationWithTimeComponent_CleansTimeComponent()
|
||||
{
|
||||
// Arrange
|
||||
var locationConfig = new LocationParsingConfiguration
|
||||
{
|
||||
LocationPatterns = new List<string> { "Exhibit Hall *" }
|
||||
};
|
||||
|
||||
// Act
|
||||
TimeLocationParser.Parse("10:00 a.m. - 12:15 p.m. Exhibit Hall C", locationConfig,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("10:00 a.m. - 12:15 p.m."));
|
||||
Assert.That(location, Is.EqualTo("Exhibit Hall C"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Parse_NoLocationConfig_StillExtractsTimeAndLocation()
|
||||
{
|
||||
// Act
|
||||
TimeLocationParser.Parse("3:00 p.m. Room A", null,
|
||||
out string time, out string location, out bool locationParseSuccess);
|
||||
|
||||
// Assert
|
||||
Assert.That(time, Is.EqualTo("3:00 p.m."));
|
||||
Assert.That(location, Is.EqualTo("Room A"));
|
||||
Assert.That(locationParseSuccess, Is.False); // No patterns to match against
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_RemovesTimeAtStart()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText("- 12:15 p.m. Exhibit Hall C");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.EqualTo("Exhibit Hall C"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_RemovesTimeWithoutDash()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText("12:15 p.m. Exhibit Hall C");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.EqualTo("Exhibit Hall C"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_RemovesNOONAtStart()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText("- NOON Exhibit Hall C");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.EqualTo("Exhibit Hall C"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_OnlyTime_ReturnsEmpty()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText("12:15 p.m.");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_EmptyString_ReturnsEmpty()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText("");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_WhitespaceOnly_ReturnsEmpty()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText(" ");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CleanLocationText_NoTimeComponent_ReturnsOriginal()
|
||||
{
|
||||
// Act
|
||||
var result = TimeLocationParser.CleanLocationText("Exhibit Hall C");
|
||||
|
||||
// Assert
|
||||
Assert.That(result, Is.EqualTo("Exhibit Hall C"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user