|
|
|
@ -1,12 +1,17 @@
|
|
|
|
|
module fahrplanparser;
|
|
|
|
|
|
|
|
|
|
import kxml.xml : readDocument, XmlNode;
|
|
|
|
|
|
|
|
|
|
import std.algorithm : map;
|
|
|
|
|
import std.array : empty, front;
|
|
|
|
|
import std.conv : to;
|
|
|
|
|
import std.datetime : dur, TimeOfDay, DateTimeException;
|
|
|
|
|
import std.string : format;
|
|
|
|
|
|
|
|
|
|
import kxml.xml : readDocument, XmlNode;
|
|
|
|
|
version (unittest)
|
|
|
|
|
{
|
|
|
|
|
import unit_threaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
import substitution;
|
|
|
|
|
|
|
|
|
@ -50,22 +55,74 @@ auto parsedFahrplan(in string data)
|
|
|
|
|
{
|
|
|
|
|
import std.array : array;
|
|
|
|
|
|
|
|
|
|
auto xml = "";
|
|
|
|
|
assert(xml.parsedFahrplan.array == []);
|
|
|
|
|
"".parsedFahrplan.array.shouldEqual([]);
|
|
|
|
|
|
|
|
|
|
xml = "<efa><dps></dps></efa>";
|
|
|
|
|
assert(xml.parsedFahrplan.array == []);
|
|
|
|
|
"<efa><dps></dps></efa>".parsedFahrplan.array.shouldEqual([]);
|
|
|
|
|
|
|
|
|
|
xml = "<efa><dps><dp><realtime>1</realtime><st><t>1224</t><rt>1242</rt></st><m><nu>6</nu><des>Wernerwerkstraße</des></m></dp></dps></efa>";
|
|
|
|
|
assert(xml.parsedFahrplan.array == [["direction" : "Wernerwerkstraße",
|
|
|
|
|
q"[
|
|
|
|
|
<efa>
|
|
|
|
|
<dps>
|
|
|
|
|
<dp>
|
|
|
|
|
<realtime>1</realtime>
|
|
|
|
|
<st>
|
|
|
|
|
<t>1224</t>
|
|
|
|
|
<rt>1242</rt>
|
|
|
|
|
</st>
|
|
|
|
|
<m>
|
|
|
|
|
<nu>6</nu>
|
|
|
|
|
<des>Wernerwerkstraße</des>
|
|
|
|
|
</m>
|
|
|
|
|
</dp>
|
|
|
|
|
</dps>
|
|
|
|
|
</efa>
|
|
|
|
|
]".parsedFahrplan.array.shouldEqual([["direction" : "Wernerwerkstraße",
|
|
|
|
|
"line" : "6", "departure" : "12:24", "delay" : "18"]]);
|
|
|
|
|
|
|
|
|
|
xml = "<efa><dps><dp><realtime>0</realtime><st><t>1224</t></st><m><nu>6</nu><des>Wernerwerkstraße</des></m></dp></dps></efa>";
|
|
|
|
|
assert(xml.parsedFahrplan.array == [["direction" : "Wernerwerkstraße",
|
|
|
|
|
q"[
|
|
|
|
|
<efa>
|
|
|
|
|
<dps>
|
|
|
|
|
<dp>
|
|
|
|
|
<realtime>0</realtime>
|
|
|
|
|
<st>
|
|
|
|
|
<t>1224</t>
|
|
|
|
|
</st>
|
|
|
|
|
<m>
|
|
|
|
|
<nu>6</nu>
|
|
|
|
|
<des>Wernerwerkstraße</des>
|
|
|
|
|
</m>
|
|
|
|
|
</dp>
|
|
|
|
|
</dps>
|
|
|
|
|
</efa>
|
|
|
|
|
]".parsedFahrplan.array.shouldEqual([["direction" : "Wernerwerkstraße",
|
|
|
|
|
"line" : "6", "departure" : "12:24", "delay" : "0"]]);
|
|
|
|
|
|
|
|
|
|
xml = "<efa><dps><dp><realtime>0</realtime><st><t>1224</t></st><m><nu>6</nu><des>Wernerwerkstraße</des></m></dp><dp><realtime>1</realtime><st><t>1353</t><rt>1356</rt></st><m><nu>11</nu><des>Burgweinting</des></m></dp></dps></efa>";
|
|
|
|
|
assert(xml.parsedFahrplan.array == [["direction" : "Wernerwerkstraße", "line" : "6",
|
|
|
|
|
q"[
|
|
|
|
|
<efa>
|
|
|
|
|
<dps>
|
|
|
|
|
<dp>
|
|
|
|
|
<realtime>0</realtime>
|
|
|
|
|
<st>
|
|
|
|
|
<t>1224</t>
|
|
|
|
|
</st>
|
|
|
|
|
<m>
|
|
|
|
|
<nu>6</nu>
|
|
|
|
|
<des>Wernerwerkstraße</des>
|
|
|
|
|
</m>
|
|
|
|
|
</dp>
|
|
|
|
|
<dp>
|
|
|
|
|
<realtime>1</realtime>
|
|
|
|
|
<st>
|
|
|
|
|
<t>1353</t>
|
|
|
|
|
<rt>1356</rt>
|
|
|
|
|
</st>
|
|
|
|
|
<m>
|
|
|
|
|
<nu>11</nu>
|
|
|
|
|
<des>Burgweinting</des>
|
|
|
|
|
</m>
|
|
|
|
|
</dp>
|
|
|
|
|
</dps>
|
|
|
|
|
</efa>
|
|
|
|
|
]".parsedFahrplan.array.shouldEqual([["direction" : "Wernerwerkstraße", "line" : "6",
|
|
|
|
|
"departure" : "12:24", "delay" : "0"], ["direction" : "Burgweinting",
|
|
|
|
|
"line" : "11", "departure" : "13:53", "delay" : "3"]]);
|
|
|
|
|
}
|
|
|
|
@ -104,41 +161,47 @@ body
|
|
|
|
|
|
|
|
|
|
@system unittest
|
|
|
|
|
{
|
|
|
|
|
import std.exception : assertThrown;
|
|
|
|
|
"<dp><st><t>0000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldEqual(TimeOfDay(0, 0));
|
|
|
|
|
|
|
|
|
|
auto xml = "<dp><st><t>0000</t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.departureTime == TimeOfDay(0, 0));
|
|
|
|
|
"<dp><st><t>0013</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldEqual(TimeOfDay(0, 13));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><st><t>0013</t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.departureTime == TimeOfDay(0, 13));
|
|
|
|
|
"<dp><st><t>1100</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldEqual(TimeOfDay(11, 00));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><st><t>1100</t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.departureTime == TimeOfDay(11, 00));
|
|
|
|
|
"<dp><st><t>1242</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldEqual(TimeOfDay(12, 42));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><st><t>1242</t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.departureTime == TimeOfDay(12, 42));
|
|
|
|
|
"<dp><st><t>2359</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldEqual(TimeOfDay(23, 59));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><st><t>2359</t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.departureTime == TimeOfDay(23, 59));
|
|
|
|
|
"<dp><st><t>2400</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>2400</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>0061</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>2567</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>0</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>00</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>000000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>00:00</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
assertThrown!DateTimeException("<dp><st><t>abcd</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime);
|
|
|
|
|
"<dp><st><t>0061</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t>2567</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t>0</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t>00</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t>000000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t>00:00</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
|
|
|
|
|
"<dp><st><t>abcd</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.departureTime.shouldThrow!DateTimeException;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto delay(XmlNode dp)
|
|
|
|
@ -173,70 +236,59 @@ body
|
|
|
|
|
|
|
|
|
|
@system unittest
|
|
|
|
|
{
|
|
|
|
|
import std.exception : assertThrown;
|
|
|
|
|
import core.exception : AssertError;
|
|
|
|
|
|
|
|
|
|
auto xml = "<dp><realtime>0</realtime></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(0));
|
|
|
|
|
"<dp><realtime>0</realtime></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(0));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime></realtime></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assertThrown!(UnexpectedValueException!string)(xml.delay);
|
|
|
|
|
"<dp><realtime></realtime></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(UnexpectedValueException!string);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>2</realtime></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assertThrown!(UnexpectedValueException!string)(xml.delay);
|
|
|
|
|
"<dp><realtime>2</realtime></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(UnexpectedValueException!string);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>a</realtime></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assertThrown!(UnexpectedValueException!string)(xml.delay);
|
|
|
|
|
"<dp><realtime>a</realtime></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(UnexpectedValueException!string);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"seconds"(0));
|
|
|
|
|
"<dp><realtime>1</realtime></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"seconds"(0));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><t></t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assertThrown!DateTimeException(xml.delay);
|
|
|
|
|
"<dp><realtime>1</realtime><st><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(DateTimeException);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt></rt></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"seconds"(0));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt></rt></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"seconds"(0));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><st><rt></rt><t></t></st></dp>".readDocument.parseXPath("/dp").front;
|
|
|
|
|
assertThrown!AssertError(xml.delay);
|
|
|
|
|
"<dp><st><rt></rt><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(AssertError);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt></rt><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front;
|
|
|
|
|
assertThrown!DateTimeException(xml.delay);
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt></rt><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(DateTimeException);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>0000</rt><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front;
|
|
|
|
|
assertThrown!DateTimeException(xml.delay);
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>0000</rt><t></t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(DateTimeException);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt></rt><t>0000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front;
|
|
|
|
|
assertThrown!DateTimeException(xml.delay);
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt></rt><t>0000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldThrow!(DateTimeException);
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>0000</rt><t>0000</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(0));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>0000</rt><t>0000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(0));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>0001</rt><t>0000</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(1));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>0001</rt><t>0000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(1));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>1753</rt><t>1751</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(2));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>1753</rt><t>1751</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(2));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>1010</rt><t>1000</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(10));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>1010</rt><t>1000</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(10));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>1301</rt><t>1242</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(19));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>1301</rt><t>1242</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(19));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>0000</rt><t>1242</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(678));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>0000</rt><t>1242</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(678));
|
|
|
|
|
|
|
|
|
|
xml = "<dp><realtime>1</realtime><st><rt>0000</rt><t>2359</t></st></dp>"
|
|
|
|
|
.readDocument.parseXPath("/dp").front;
|
|
|
|
|
assert(xml.delay == dur!"minutes"(1));
|
|
|
|
|
"<dp><realtime>1</realtime><st><rt>0000</rt><t>2359</t></st></dp>".readDocument.parseXPath("/dp")
|
|
|
|
|
.front.delay.shouldEqual(dur!"minutes"(1));
|
|
|
|
|
}
|
|
|
|
|