File indexing completed on 2024-05-19 05:17:50
0001 /* 0002 SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include <KItinerary/Flight> 0008 #include <KItinerary/JsonLdDocument> 0009 #include <KItinerary/Organization> 0010 #include <KItinerary/Place> 0011 #include <KItinerary/Reservation> 0012 #include <KItinerary/Person> 0013 #include <KItinerary/Taxi> 0014 #include <KItinerary/RentalCar> 0015 #include <KItinerary/Brand> 0016 0017 #include <QDebug> 0018 #include <QJsonArray> 0019 #include <QJsonDocument> 0020 #include <QJsonObject> 0021 #include <QObject> 0022 #include <QProcess> 0023 #include <QTest> 0024 #include <QTimeZone> 0025 0026 using namespace KItinerary; 0027 0028 class JsonLdDocumentTest : public QObject 0029 { 0030 Q_OBJECT 0031 private: 0032 QByteArray readFile(const QString &fn) 0033 { 0034 QFile f(fn); 0035 f.open(QFile::ReadOnly); 0036 return f.readAll(); 0037 } 0038 0039 private Q_SLOTS: 0040 void initTestCase() 0041 { 0042 qputenv("TZ", "America/Chicago"); 0043 } 0044 0045 void testSerialization() 0046 { 0047 Flight f; 0048 f.setFlightNumber(QStringLiteral("1234")); 0049 f.setDepartureTime(QDateTime(QDate(2018, 3, 18), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0050 f.setDepartureDay(QDate(2018, 3, 18)); 0051 f.setArrivalTime(QDateTime(QDate(2018, 3, 18), QTime(19, 44, 0), QTimeZone::UTC)); 0052 Airport ap; 0053 ap.setName(QStringLiteral("Berlin Tegel")); 0054 ap.setIataCode(QStringLiteral("TXL")); 0055 f.setDepartureAirport(ap); 0056 f.setDepartureGate(QLatin1StringView("")); 0057 Airline airline; 0058 airline.setIataCode(QStringLiteral("LH")); 0059 f.setAirline(airline); 0060 0061 auto array = 0062 JsonLdDocument::toJson(QList<QVariant>({QVariant::fromValue(f)})); 0063 QCOMPARE(array.size(), 1); 0064 auto obj = array.at(0).toObject(); 0065 QCOMPARE(obj.value(QLatin1StringView("@context")).toString(), 0066 QLatin1String("http://schema.org")); 0067 QCOMPARE(obj.value(QLatin1StringView("@type")).toString(), 0068 QLatin1String("Flight")); 0069 QCOMPARE(obj.value(QLatin1StringView("flightNumber")).toString(), 0070 QLatin1String("1234")); 0071 0072 QCOMPARE(obj.value(QLatin1StringView("arrivalTime")).toString(), 0073 QLatin1String("2018-03-18T19:44:00Z")); 0074 auto dtObj = obj.value(QLatin1StringView("departureTime")).toObject(); 0075 QCOMPARE(dtObj.value(QLatin1StringView("@value")).toString(), 0076 QLatin1String("2018-03-18T18:44:00+01:00")); 0077 QCOMPARE(dtObj.value(QLatin1StringView("@type")).toString(), 0078 QLatin1String("QDateTime")); 0079 QCOMPARE(dtObj.value(QLatin1StringView("timezone")).toString(), 0080 QLatin1String("Europe/Berlin")); 0081 QCOMPARE(obj.value(QLatin1StringView("departureDay")).toString(), 0082 QLatin1String("2018-03-18")); 0083 0084 auto obj2 = obj.value(QLatin1StringView("departureAirport")).toObject(); 0085 QCOMPARE(obj2.value(QLatin1StringView("@type")).toString(), 0086 QLatin1String("Airport")); 0087 0088 QVERIFY(obj.contains(QLatin1StringView("departureGate"))); 0089 QCOMPARE(obj.value(QLatin1StringView("departureGate")).toString(), 0090 QLatin1String("")); 0091 0092 QVERIFY(obj.contains(QLatin1StringView("airline"))); 0093 0094 qDebug().noquote() << QJsonDocument(obj).toJson(); 0095 0096 // integer values 0097 FoodEstablishmentReservation res; 0098 res.setPartySize(2); 0099 const QString reservationNumber{QStringLiteral("OT123456")}; 0100 res.setReservationNumber(reservationNumber); 0101 res.setStartTime(QDateTime(QDate(2018, 3, 18), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0102 Person person; 0103 const QString fullName{QStringLiteral("John")}; 0104 0105 person.setName(fullName); 0106 res.setUnderName(person); 0107 0108 array = JsonLdDocument::toJson(QList<QVariant>({res})); 0109 QCOMPARE(array.size(), 1); 0110 obj = array.at(0).toObject(); 0111 QCOMPARE(obj.value(QLatin1StringView("partySize")).toInt(), 2); 0112 QCOMPARE(obj.value(QLatin1StringView("reservationNumber")).toString(), 0113 reservationNumber); 0114 auto resDtObj = obj.value(QLatin1StringView("startTime")).toObject(); 0115 QCOMPARE(resDtObj.value(QLatin1StringView("@value")).toString(), 0116 QLatin1String("2018-03-18T18:44:00+01:00")); 0117 QCOMPARE(resDtObj.value(QLatin1StringView("@type")).toString(), 0118 QLatin1String("QDateTime")); 0119 QCOMPARE(resDtObj.value(QLatin1StringView("timezone")).toString(), 0120 QLatin1String("Europe/Berlin")); 0121 qDebug().noquote() << QJsonDocument(obj).toJson(); 0122 auto undernameObj = 0123 obj.value(QLatin1StringView("underName")).toObject(); 0124 QCOMPARE(undernameObj.value(QLatin1StringView("name")).toString(), 0125 QLatin1String("John")); 0126 0127 //Rental Car 0128 RentalCarReservation rentalRes; 0129 const QString reservationRentalNumber{QStringLiteral("OT1234567")}; 0130 rentalRes.setReservationNumber(reservationRentalNumber); 0131 Person personRentalCal; 0132 const QString fullNameRentalCar{QStringLiteral("John2")}; 0133 0134 personRentalCal.setName(fullNameRentalCar); 0135 rentalRes.setUnderName(personRentalCal); 0136 rentalRes.setPickupTime(QDateTime(QDate(2018, 3, 18), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0137 rentalRes.setDropoffTime(QDateTime(QDate(2018, 3, 21), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0138 0139 Place placeDropLocation; 0140 placeDropLocation.setName(QStringLiteral("droplocation")); 0141 KItinerary::PostalAddress placeDropPostalAddress; 0142 placeDropPostalAddress.setStreetAddress(QStringLiteral("8 foo bla bla")); 0143 placeDropPostalAddress.setAddressLocality(QStringLiteral("bli")); 0144 placeDropLocation.setAddress(placeDropPostalAddress); 0145 0146 rentalRes.setDropoffLocation(placeDropLocation); 0147 0148 Place placePickupLocation; 0149 placePickupLocation.setName(QStringLiteral("pickuplocation")); 0150 KItinerary::PostalAddress placePickupPostalAddress; 0151 placePickupPostalAddress.setStreetAddress(QStringLiteral("5 kde foo bla bla")); 0152 placePickupPostalAddress.setAddressLocality(QStringLiteral("bli2")); 0153 placePickupLocation.setAddress(placePickupPostalAddress); 0154 0155 rentalRes.setPickupLocation(placePickupLocation); 0156 0157 obj = JsonLdDocument::toJson(rentalRes); 0158 QCOMPARE(obj.value(QLatin1StringView("reservationNumber")).toString(), 0159 reservationRentalNumber); 0160 0161 qDebug().noquote() << QJsonDocument(obj).toJson(); 0162 undernameObj = obj.value(QLatin1StringView("underName")).toObject(); 0163 QCOMPARE(undernameObj.value(QLatin1StringView("name")).toString(), 0164 fullNameRentalCar); 0165 0166 auto pickupTimeObj = 0167 obj.value(QLatin1StringView("dropoffTime")).toObject(); 0168 QCOMPARE(pickupTimeObj.value(QLatin1StringView("@value")).toString(), 0169 QLatin1String("2018-03-21T18:44:00+01:00")); 0170 QCOMPARE(pickupTimeObj.value(QLatin1StringView("@type")).toString(), 0171 QLatin1String("QDateTime")); 0172 QCOMPARE(pickupTimeObj.value(QLatin1StringView("timezone")).toString(), 0173 QLatin1String("Europe/Berlin")); 0174 0175 auto droptimeObj = 0176 obj.value(QLatin1StringView("pickupTime")).toObject(); 0177 QCOMPARE(droptimeObj.value(QLatin1StringView("@value")).toString(), 0178 QLatin1String("2018-03-18T18:44:00+01:00")); 0179 QCOMPARE(droptimeObj.value(QLatin1StringView("@type")).toString(), 0180 QLatin1String("QDateTime")); 0181 QCOMPARE(droptimeObj.value(QLatin1StringView("timezone")).toString(), 0182 QLatin1String("Europe/Berlin")); 0183 } 0184 0185 void testDeserialization() 0186 { 0187 QByteArray b("[{" 0188 "\"@context\": \"http://schema.org\"," 0189 "\"@type\": \"Flight\"," 0190 "\"departureAirport\": {" 0191 "\"@type\": \"Airport\"," 0192 "\"iataCode\": \"TXL\"," 0193 "\"name\": \"Berlin Tegel\"" 0194 "}," 0195 "\"departureTime\": \"2018-03-18T18:44:00+01:00\"," 0196 "\"departureDay\": \"2018-03-17\"," 0197 "\"arrivalTime\": { \"@type\": \"QDateTime\", \"@value\": \"2018-03-18T19:44:00+01:00\", \"timezone\": \"Europe/Berlin\" }," 0198 "\"departureGate\": \"\"," 0199 "\"flightNumber\": \"1234\"" 0200 "}]"); 0201 0202 auto array = QJsonDocument::fromJson(b).array(); 0203 auto datas = JsonLdDocument::fromJson(array); 0204 QCOMPARE(datas.size(), 1); 0205 0206 auto data = datas.at(0); 0207 QVERIFY(data.canConvert<Flight>()); 0208 auto flight = data.value<Flight>(); 0209 QCOMPARE(flight.flightNumber(), QLatin1StringView("1234")); 0210 QCOMPARE(flight.departureAirport().iataCode(), 0211 QLatin1StringView("TXL")); 0212 QCOMPARE(flight.departureAirport().name(), 0213 QLatin1StringView("Berlin Tegel")); 0214 QCOMPARE(flight.departureTime(), QDateTime(QDate(2018, 3, 18), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0215 QCOMPARE(flight.departureDay(), QDate(2018, 3, 17)); 0216 QCOMPARE(flight.arrivalTime(), QDateTime(QDate(2018, 3, 18), QTime(19, 44, 0), QTimeZone("Europe/Berlin"))); 0217 QCOMPARE(flight.arrivalTime().timeSpec(), Qt::TimeZone); 0218 QCOMPARE(flight.arrivalTime().timeZone(), QTimeZone("Europe/Berlin")); 0219 0220 QVERIFY(flight.departureGate().isEmpty()); 0221 QVERIFY(!flight.departureGate().isNull()); 0222 0223 // integer values 0224 b = QByteArray("[{" 0225 "\"@context\": \"http://schema.org\"," 0226 "\"@type\": \"FoodEstablishmentReservation\"," 0227 "\"partySize\": 42," 0228 "\"reservationNumber\": \"0T44542\"," 0229 "\"underName\": {" 0230 " \"@type\": \"Person\"," 0231 " \"name\": \"John Smith\"," 0232 " \"email\": \"foo@kde.org\"" 0233 "}," 0234 "\"reservationFor\": {" 0235 " \"@type\": \"FoodEstablishment\"," 0236 " \"name\": \"Wagamama\"," 0237 " \"address\": {" 0238 " \"@type\": \"PostalAddress\"," 0239 " \"streetAddress\": \"1 Tavistock Street\"," 0240 " \"addressLocality\": \"London\"," 0241 " \"addressRegion\": \"Greater London\"," 0242 " \"postalCode\": \"WC2E 7PG\"," 0243 " \"addressCountry\": \"United Kingdom\"" 0244 " }" 0245 "}" 0246 "}]"); 0247 0248 array = QJsonDocument::fromJson(b).array(); 0249 datas = JsonLdDocument::fromJson(array); 0250 QCOMPARE(datas.size(), 1); 0251 data = datas.at(0); 0252 QVERIFY(data.canConvert<FoodEstablishmentReservation>()); 0253 auto res = data.value<FoodEstablishmentReservation>(); 0254 QCOMPARE(res.partySize(), 42); 0255 QCOMPARE(res.reservationNumber(), QStringLiteral("0T44542")); 0256 QCOMPARE(res.underName().value<Person>().name(), QStringLiteral("John Smith")); 0257 QCOMPARE(res.underName().value<Person>().email(), QStringLiteral("foo@kde.org")); 0258 0259 const auto foodEstablishment = res.reservationFor().value<FoodEstablishment>(); 0260 const auto address = foodEstablishment.address(); 0261 QCOMPARE(address.addressCountry(), QStringLiteral("United Kingdom")); 0262 QCOMPARE(address.addressLocality(), QStringLiteral("London")); 0263 QCOMPARE(address.postalCode(), QStringLiteral("WC2E 7PG")); 0264 QCOMPARE(address.streetAddress(), QStringLiteral("1 Tavistock Street")); 0265 QCOMPARE(address.addressRegion(), QStringLiteral("Greater London")); 0266 0267 //RentalCar 0268 b = QByteArray("[{" 0269 "\"@context\": \"http://schema.org\"," 0270 "\"@type\": \"RentalCarReservation\"," 0271 "\"reservationNumber\": \"0T445424\"," 0272 "\"underName\": {" 0273 " \"@type\": \"Person\"," 0274 " \"name\": \"John Smith\"," 0275 " \"email\": \"foo@kde.org\"" 0276 "}," 0277 "\"pickupLocation\": {" 0278 " \"@type\": \"Place\"," 0279 " \"address\": {" 0280 " \"@type\": \"PostalAddress\"," 0281 " \"addressLocality\": \"bli2\"," 0282 " \"streetAddress\": \"5 kde foo bla bla\"" 0283 "}," 0284 "\"name\": \"pickuplocation\"" 0285 "}," 0286 "\"dropoffLocation\": {" 0287 " \"@type\": \"Place\"," 0288 " \"address\": {" 0289 " \"@type\": \"PostalAddress\"," 0290 " \"addressLocality\": \"bli3\"," 0291 " \"streetAddress\": \"7 kde foo bla bla\"" 0292 "}," 0293 "\"name\": \"droplocation\"" 0294 "}," 0295 "\"reservationFor\": {" 0296 " \"@type\": \"RentalCar\"," 0297 " \"name\": \"Economy Class Car\"," 0298 " \"model\": \"Civic\"," 0299 " \"brand\": {" 0300 " \"@type\": \"Brand\"," 0301 " \"name\": \"Honda\"" 0302 " }," 0303 " \"rentalCompany\": {" 0304 " \"@type\": \"Organization\"," 0305 " \"name\": \"Hertz\"" 0306 " }" 0307 "}," 0308 "\"pickupTime\": \"2018-03-18T18:44:00+01:00\"," 0309 "\"dropoffTime\": \"2018-03-21T18:44:00+01:00\"" 0310 "}]"); 0311 0312 array = QJsonDocument::fromJson(b).array(); 0313 datas = JsonLdDocument::fromJson(array); 0314 QCOMPARE(datas.size(), 1); 0315 data = datas.at(0); 0316 QVERIFY(data.canConvert<RentalCarReservation>()); 0317 auto resRentCar = data.value<RentalCarReservation>(); 0318 QCOMPARE(resRentCar.reservationNumber(), QStringLiteral("0T445424")); 0319 QCOMPARE(resRentCar.underName().value<Person>().name(), QStringLiteral("John Smith")); 0320 QCOMPARE(resRentCar.underName().value<Person>().email(), QStringLiteral("foo@kde.org")); 0321 QCOMPARE(resRentCar.pickupTime(), QDateTime(QDate(2018, 3, 18), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0322 QCOMPARE(resRentCar.dropoffTime(), QDateTime(QDate(2018, 3, 21), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0323 const auto dropoffLocation = resRentCar.dropoffLocation(); 0324 QCOMPARE(dropoffLocation.name(), QStringLiteral("droplocation")); 0325 const auto dropOffLocationAddress = dropoffLocation.address(); 0326 QCOMPARE(dropOffLocationAddress.streetAddress(), QStringLiteral("7 kde foo bla bla")); 0327 QCOMPARE(dropOffLocationAddress.addressLocality(), QStringLiteral("bli3")); 0328 0329 const auto pickupLocation = resRentCar.pickupLocation(); 0330 QCOMPARE(pickupLocation.name(), QStringLiteral("pickuplocation")); 0331 const auto pickupLocationAddress = pickupLocation.address(); 0332 QCOMPARE(pickupLocationAddress.streetAddress(), QStringLiteral("5 kde foo bla bla")); 0333 QCOMPARE(pickupLocationAddress.addressLocality(), QStringLiteral("bli2")); 0334 0335 const auto reservationForRentalCar = resRentCar.reservationFor().value<RentalCar>(); 0336 QCOMPARE(reservationForRentalCar.name(), QStringLiteral("Economy Class Car")); 0337 QCOMPARE(reservationForRentalCar.model(), QStringLiteral("Civic")); 0338 const auto brand = reservationForRentalCar.brand(); 0339 QCOMPARE(brand.name(), QStringLiteral("Honda")); 0340 0341 const auto rentalCarOrganization = reservationForRentalCar.rentalCompany(); 0342 QCOMPARE(rentalCarOrganization.name(), QStringLiteral("Hertz")); 0343 0344 //Taxi Reservation 0345 b = QByteArray("[{" 0346 "\"@context\": \"http://schema.org\"," 0347 "\"@type\": \"TaxiReservation\"," 0348 "\"reservationId\": \"0T445424\"," 0349 "\"underName\": {" 0350 " \"@type\": \"Person\"," 0351 " \"name\": \"John Smith2\"," 0352 " \"email\": \"foo@kde.org\"" 0353 "}," 0354 "\"pickupLocation\": {" 0355 " \"@type\": \"Place\"," 0356 " \"address\": {" 0357 " \"@type\": \"PostalAddress\"," 0358 " \"addressLocality\": \"bli2\"," 0359 " \"streetAddress\": \"5 kde foo bla bla\"" 0360 " }" 0361 "}," 0362 "\"reservationFor\": {" 0363 " \"@type\": \"Taxi\"," 0364 " \"provider\": {" 0365 " \"@type\": \"Organization\"," 0366 " \"name\": \"Checker Cab\"" 0367 " }" 0368 "}," 0369 "\"pickupTime\": \"2018-03-18T18:44:00+01:00\"" 0370 "}]"); 0371 array = QJsonDocument::fromJson(b).array(); 0372 datas = JsonLdDocument::fromJson(array); 0373 QCOMPARE(datas.size(), 1); 0374 data = datas.at(0); 0375 QVERIFY(data.canConvert<TaxiReservation>()); 0376 auto resTaxi = data.value<TaxiReservation>(); 0377 QCOMPARE(resTaxi.reservationNumber(), QStringLiteral("0T445424")); 0378 QCOMPARE(resTaxi.underName().value<Person>().name(), QStringLiteral("John Smith2")); 0379 QCOMPARE(resTaxi.underName().value<Person>().email(), QStringLiteral("foo@kde.org")); 0380 0381 const auto pickUpLocationTaxi = resTaxi.pickupLocation(); 0382 const auto pickupLocationAddressTaxi = pickUpLocationTaxi.address(); 0383 QCOMPARE(pickupLocationAddressTaxi.streetAddress(), QStringLiteral("5 kde foo bla bla")); 0384 QCOMPARE(pickupLocationAddressTaxi.addressLocality(), QStringLiteral("bli2")); 0385 0386 QCOMPARE(resTaxi.pickupTime(), QDateTime(QDate(2018, 3, 18), QTime(18, 44, 0), QTimeZone("Europe/Berlin"))); 0387 QVERIFY(resTaxi.reservationFor().canConvert<Taxi>()); 0388 } 0389 0390 void testApply() 0391 { 0392 Flight f1; 0393 f1.setDepartureGate(QStringLiteral("38")); 0394 Airline a1; 0395 a1.setIataCode(QStringLiteral("AB")); 0396 f1.setAirline(a1); 0397 0398 Flight f2; 0399 f2.setDepartureTerminal(QStringLiteral("A")); 0400 Airline a2; 0401 a2.setName(QStringLiteral("Air Berlin")); 0402 f2.setAirline(a2); 0403 0404 f1 = JsonLdDocument::apply(f1, f2).value<Flight>(); 0405 QCOMPARE(f1.departureGate(), QLatin1StringView("38")); 0406 QCOMPARE(f1.departureTerminal(), QLatin1StringView("A")); 0407 QCOMPARE(f1.airline().iataCode(), QLatin1StringView("AB")); 0408 QCOMPARE(f1.airline().name(), QLatin1StringView("Air Berlin")); 0409 } 0410 0411 void testDateTimeParsing_data() 0412 { 0413 QTest::addColumn<QByteArray>("dtStr"); 0414 QTest::addColumn<QDateTime>("result"); 0415 0416 QTest::newRow("iso") << QByteArray("2018-08-15T22:00:00+02:00") << QDateTime({2018, 8, 15}, {22 ,00}, QTimeZone::fromSecondsAheadOfUtc(7200)); 0417 QTest::newRow("weird LH format") << QByteArray("20200826T200000Z") << QDateTime({2020, 8, 26}, {20 ,00}, QTimeZone::UTC); 0418 } 0419 0420 void testDateTimeParsing() 0421 { 0422 QFETCH(QByteArray, dtStr); 0423 QFETCH(QDateTime, result); 0424 0425 const auto b = QByteArray("[{" 0426 "\"@context\": \"http://schema.org\"," 0427 "\"@type\": \"Flight\"," 0428 "\"departureTime\": \"" + dtStr + "\"" 0429 "}]"); 0430 const auto array = QJsonDocument::fromJson(b).array(); 0431 const auto data = JsonLdDocument::fromJson(array); 0432 QCOMPARE(data.size(), 1); 0433 const auto flight = data[0].value<Flight>(); 0434 QCOMPARE(flight.departureTime(), result); 0435 QCOMPARE(flight.departureTime().timeSpec(), result.timeSpec()); 0436 } 0437 0438 void testNormalize_data() 0439 { 0440 QTest::addColumn<QString>("inFile"); 0441 QTest::addColumn<QString>("refFile"); 0442 0443 QDir dir(QStringLiteral(SOURCE_DIR "/jsonlddata")); 0444 const auto lst = dir.entryList(QStringList(QStringLiteral("*.in.json")), QDir::Files | QDir::Readable | QDir::NoSymLinks); 0445 for (const auto &file : lst) { 0446 const QString refFile = dir.path() + QLatin1Char('/') + file.left(file.size() - 7) + QStringLiteral("out.json"); 0447 if (!QFile::exists(refFile)) { 0448 qDebug() << "reference file" << refFile << "does not exist, skipping test file" << file; 0449 continue; 0450 } 0451 QTest::newRow(file.toLatin1().constData()) << QString(dir.path() + QLatin1Char('/') + file) << refFile; 0452 } 0453 } 0454 0455 void testNormalize() 0456 { 0457 QFETCH(QString, inFile); 0458 QFETCH(QString, refFile); 0459 0460 const auto inJson = QJsonDocument::fromJson(readFile(inFile)).array(); 0461 QVERIFY(!inJson.isEmpty()); 0462 const auto normalizedJson = JsonLdDocument::toJson(JsonLdDocument::fromJson(inJson)); 0463 QVERIFY(!normalizedJson.isEmpty()); 0464 const auto refJson = QJsonDocument::fromJson(readFile(refFile)).array(); 0465 QVERIFY(!refJson.isEmpty()); 0466 0467 qDebug() << normalizedJson; 0468 if (normalizedJson != refJson) { 0469 QFile f(refFile + QLatin1StringView(".fail")); 0470 QVERIFY(f.open(QFile::WriteOnly)); 0471 f.write(QJsonDocument(normalizedJson).toJson()); 0472 f.close(); 0473 0474 QProcess proc; 0475 proc.setProcessChannelMode(QProcess::ForwardedChannels); 0476 proc.start(QStringLiteral("diff"), 0477 {QStringLiteral("-u"), refFile, f.fileName()}); 0478 QVERIFY(proc.waitForFinished()); 0479 } 0480 QCOMPARE(normalizedJson, refJson); 0481 } 0482 }; 0483 0484 QTEST_APPLESS_MAIN(JsonLdDocumentTest) 0485 0486 #include "jsonlddocumenttest.moc"