File indexing completed on 2024-05-12 05:17:29
0001 /* 0002 SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org> 0003 SPDX-FileCopyrightText: 2018 Luca Beltrame <lbeltrame@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include <KItinerary/BusTrip> 0009 #include <KItinerary/Flight> 0010 #include <KItinerary/Organization> 0011 #include <KItinerary/Place> 0012 #include <KItinerary/Reservation> 0013 #include <KItinerary/TrainTrip> 0014 #include <KItinerary/Ticket> 0015 0016 #include <KItinerary/JsonLdDocument> 0017 0018 #include <QDebug> 0019 #include <QQmlComponent> 0020 #include <QQmlContext> 0021 #include <QQmlEngine> 0022 #include <QObject> 0023 #include <QTest> 0024 0025 using namespace KItinerary; 0026 0027 class DatatypesTest : public QObject 0028 { 0029 Q_OBJECT 0030 private Q_SLOTS: 0031 void testValueTypeSemantics() 0032 { 0033 Airport airport; 0034 airport.setName(QStringLiteral("Berlin Tegel")); 0035 { 0036 auto ap2 = airport; 0037 QCOMPARE(ap2.name(), QLatin1StringView("Berlin Tegel")); 0038 ap2.setIataCode(QStringLiteral("TXL")); 0039 QVERIFY(airport.iataCode().isEmpty()); 0040 } 0041 Place place = airport; // assignment to base class works, but cannot be reversed 0042 QCOMPARE(place.name(), QLatin1StringView("Berlin Tegel")); 0043 place.setName(QStringLiteral("London Heathrow")); // changing a value degenerated to its base class will detach but not slice 0044 QCOMPARE(place.name(), QLatin1StringView("London Heathrow")); 0045 QCOMPARE(JsonLdDocument::readProperty(place, "className").toString(), 0046 QLatin1StringView("Place")); // className is not polymorphic 0047 0048 QVERIFY(!airport.geo().isValid()); 0049 QCOMPARE(JsonLdDocument::readProperty(airport, "className").toString(), 0050 QLatin1StringView("Airport")); 0051 QCOMPARE(JsonLdDocument::readProperty(airport, "name").toString(), 0052 QLatin1StringView("Berlin Tegel")); 0053 0054 // detach on base properties must not slice 0055 FlightReservation res; 0056 QCOMPARE(JsonLdDocument::readProperty(res, "className").toString(), 0057 QLatin1StringView("FlightReservation")); 0058 res.setAirplaneSeat(QStringLiteral("10E")); 0059 QCOMPARE(res.airplaneSeat(), QLatin1StringView("10E")); 0060 auto res2 = res; 0061 QCOMPARE(res2.airplaneSeat(), QLatin1StringView("10E")); 0062 res2.setReservationNumber(QStringLiteral("XXX007")); 0063 QCOMPARE(res2.airplaneSeat(), QLatin1StringView("10E")); 0064 0065 // changing default-created properties should not leak 0066 Flight flight; 0067 QCOMPARE(JsonLdDocument::readProperty(flight, "className").toString(), 0068 QLatin1StringView("Flight")); 0069 QVariant v = flight; 0070 QVERIFY(v.canConvert<Flight>()); 0071 JsonLdDocument::writeProperty(v, "departureAirport", airport); 0072 QCOMPARE(v.value<Flight>().departureAirport().name(), 0073 QLatin1StringView("Berlin Tegel")); 0074 0075 // make sure all meta types are generated 0076 TrainTrip tt; 0077 QCOMPARE(JsonLdDocument::readProperty(tt, "className").toString(), 0078 QLatin1StringView("TrainTrip")); 0079 BusTrip bus; 0080 QCOMPARE(JsonLdDocument::readProperty(bus, "className").toString(), 0081 QLatin1StringView("BusTrip")); 0082 0083 Ticket ticket; 0084 QCOMPARE( 0085 JsonLdDocument::readProperty(ticket.ticketedSeat(), "className") 0086 .toString(), 0087 QLatin1StringView("Seat")); 0088 0089 Organization org; 0090 org.setName(QStringLiteral("JR East")); 0091 org.setEmail(QStringLiteral("nowhere@nowhere.com")); 0092 org.setTelephone(QStringLiteral("+55-1234-345")); 0093 org.setUrl(QUrl(QStringLiteral("http://www.jreast.co.jp/e/"))); 0094 QCOMPARE(JsonLdDocument::readProperty(org, "className").toString(), 0095 QLatin1StringView("Organization")); 0096 QCOMPARE(org.name(), QLatin1StringView("JR East")); 0097 QCOMPARE(org.email(), QLatin1StringView("nowhere@nowhere.com")); 0098 QCOMPARE(org.telephone(), QLatin1StringView("+55-1234-345")); 0099 QCOMPARE(org.url(), 0100 QUrl(QLatin1StringView("http://www.jreast.co.jp/e/"))); 0101 0102 tt.setProvider(org); 0103 res.setProvider(org); 0104 bus.setProvider(org); 0105 QCOMPARE(tt.provider().name(), QLatin1StringView("JR East")); 0106 QCOMPARE(tt.provider().email(), 0107 QLatin1StringView("nowhere@nowhere.com")); 0108 QCOMPARE(res.provider().name(), QLatin1StringView("JR East")); 0109 QCOMPARE(res.provider().email(), 0110 QLatin1StringView("nowhere@nowhere.com")); 0111 QCOMPARE(bus.provider().name(), QLatin1StringView("JR East")); 0112 QCOMPARE(bus.provider().email(), 0113 QLatin1StringView("nowhere@nowhere.com")); 0114 0115 Airline airline; 0116 airline.setIataCode(QStringLiteral("LH")); 0117 flight.setAirline(airline); 0118 QCOMPARE(flight.airline().iataCode(), QLatin1StringView("LH")); 0119 { 0120 const auto flight2 = flight; 0121 QCOMPARE(flight2.airline().iataCode(), QLatin1StringView("LH")); 0122 QCOMPARE(JsonLdDocument::readProperty(flight.airline(), "className") 0123 .toString(), 0124 QLatin1StringView("Airline")); 0125 QCOMPARE(JsonLdDocument::readProperty(flight.airline(), "iataCode") 0126 .toString(), 0127 QLatin1StringView("LH")); 0128 } 0129 } 0130 0131 void testQmlCompatibility() 0132 { 0133 // one variant and one typed property 0134 FlightReservation res; 0135 Flight flight; 0136 Airport airport; 0137 airport.setName(QStringLiteral("Berlin Tegel")); 0138 flight.setDepartureAirport(airport); 0139 res.setReservationFor(flight); 0140 0141 QQmlEngine engine; 0142 engine.rootContext()->setContextProperty(QStringLiteral("_res"), res); 0143 QQmlComponent component(&engine); 0144 component.setData("import QtQml 2.2\nQtObject { Component.onCompleted: console.log(_res.reservationFor.departureAirport.name); }", QUrl()); 0145 if (component.status() == QQmlComponent::Error) { 0146 qWarning() << component.errorString(); 0147 } 0148 QCOMPARE(component.status(), QQmlComponent::Ready); 0149 auto obj = component.create(); 0150 QVERIFY(obj); 0151 } 0152 0153 void testUpCastHelper() 0154 { 0155 Place p; 0156 FoodEstablishment r; 0157 Airport a; 0158 a.setName(QStringLiteral("Berlin Tegel")); 0159 a.setIataCode(QStringLiteral("TXL")); 0160 0161 QVERIFY(JsonLd::canConvert<Place>(a)); 0162 QVERIFY(JsonLd::canConvert<Airport>(a)); 0163 QVERIFY(!JsonLd::canConvert<FoodEstablishment>(a)); 0164 QVERIFY(!JsonLd::canConvert<Airport>(p)); 0165 0166 p = JsonLd::convert<Place>(a); 0167 QCOMPARE(p.name(), QLatin1StringView("Berlin Tegel")); 0168 } 0169 0170 void testCompare() 0171 { 0172 Place p1; 0173 Place p2; // base type 0174 QCOMPARE(p1, p2); 0175 QCOMPARE(p1, p1); 0176 p1.setName(QStringLiteral("Berlin")); 0177 QVERIFY(!(p1 == p2)); 0178 QVERIFY(p1 != p2); 0179 QCOMPARE(p1, p1); 0180 p2.setName(QStringLiteral("Berlin")); 0181 QCOMPARE(p1, p2); 0182 0183 GeoCoordinates coord1; 0184 GeoCoordinates coord2; // primitive types 0185 QCOMPARE(coord1, coord2); 0186 QCOMPARE(coord1, coord1); 0187 coord1 = { 52.5, 13.8 }; 0188 QVERIFY(!(coord1 == coord2)); 0189 0190 p1.setGeo(coord1); 0191 p2.setGeo({52.5, 13.8}); 0192 QCOMPARE(p1, p2); 0193 0194 Airport a1; 0195 Airport a2; // polymorphic types 0196 a1.setIataCode(QStringLiteral("TXL")); 0197 a2.setIataCode(QStringLiteral("TXL")); 0198 QCOMPARE(a1, a2); 0199 a1.setName(QStringLiteral("Berlin Tegel")); 0200 QVERIFY(a1 != a2); 0201 a2.setName(QStringLiteral("Berlin Tegel")); 0202 QCOMPARE(a1, a2); 0203 QCOMPARE(a1, a1); 0204 0205 Flight f1; 0206 f1.setDepartureAirport(a1); 0207 Flight f2; 0208 f2.setDepartureAirport(a2); 0209 QCOMPARE(f1, f2); 0210 0211 FlightReservation r1; 0212 r1.setReservationFor(f1); 0213 FlightReservation r2; 0214 r2.setReservationFor(f2); 0215 QCOMPARE(r1, r2); 0216 } 0217 0218 void testStrictDateTimeHandling() 0219 { 0220 LodgingReservation r; 0221 r.setCheckinTime(QDateTime({2023, 12, 23}, {15, 1}, QTimeZone::UTC)); 0222 QCOMPARE(r.checkinTime(), QDateTime({2023, 12, 23}, {15, 1}, QTimeZone::UTC)); 0223 QCOMPARE(r.checkinTime().timeSpec(), Qt::UTC); 0224 r.setCheckinTime(QDateTime({2023, 12, 23}, {16, 1}, QTimeZone::fromSecondsAheadOfUtc(3600))); 0225 QCOMPARE(r.checkinTime(), QDateTime({2023, 12, 23}, {15, 1}, QTimeZone::UTC)); 0226 QCOMPARE(r.checkinTime().timeSpec(), Qt::OffsetFromUTC); 0227 r.setCheckinTime(QDateTime({2023, 12, 23}, {16, 1}, QTimeZone("Europe/Brussels"))); 0228 QCOMPARE(r.checkinTime(), QDateTime({2023, 12, 23}, {15, 1}, QTimeZone::UTC)); 0229 QCOMPARE(r.checkinTime().timeSpec(), Qt::TimeZone); 0230 } 0231 }; 0232 0233 QTEST_GUILESS_MAIN(DatatypesTest) 0234 0235 #include "datatypestest.moc"