diff options
| -rw-r--r-- | src/config.cpp | 16 | ||||
| -rw-r--r-- | tests/test_config.cpp | 50 |
2 files changed, 62 insertions, 4 deletions
diff --git a/src/config.cpp b/src/config.cpp index 9edba50..ae26555 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -589,16 +589,24 @@ bool Config::saveSavedQueries() const QJsonArray array; for (const SavedQuery &query : m_savedQueries) { + // Only what carries information. The file is hand-editable, so a key + // that always holds the same value, or one the generator already + // implies, is just something the reader has to skip past. Same reason + // `pinned` and `account` are written only when set. QJsonObject object; object.insert(QStringLiteral("name"), query.name); - object.insert(QStringLiteral("query"), query.query); + if (query.isGenerated()) { + object.insert(QStringLiteral("generated"), query.generated); + } else { + object.insert(QStringLiteral("query"), query.query); + } if (query.pinned) object.insert(QStringLiteral("pinned"), true); if (!query.account.isEmpty()) object.insert(QStringLiteral("account"), query.account); - if (query.isGenerated()) - object.insert(QStringLiteral("generated"), query.generated); - if (query.flat) + // Skipped when the generator already implies it, which loadSavedQueries + // reapplies on the way back in. + if (query.flat && query.generated != QStringLiteral("sent")) object.insert(QStringLiteral("flat"), true); for (auto it = query.unknown.begin(); it != query.unknown.end(); ++it) object.insert(it.key(), it.value()); diff --git a/tests/test_config.cpp b/tests/test_config.cpp index dfe463b..3b094ba 100644 --- a/tests/test_config.cpp +++ b/tests/test_config.cpp @@ -67,6 +67,7 @@ private slots: void anUnknownGeneratorResolvesToNothingAndReports(); void migrationAddsSentWhenAnAccountHasOne(); void migrationAddsNoSentWithoutTheKey(); + void aGeneratedEntryWritesNoRedundantKeys(); void generalSectionKeysAreActuallyRead(); void messageZoomDefaultsAndValidates(); void messageZoomOutOfRangeIsReported(); @@ -1572,5 +1573,54 @@ void TestConfig::migrationAddsNoSentWithoutTheKey() QCOMPARE(queries.at(0).name, QStringLiteral("Inbox")); } +/// The file is meant to be hand-edited, so a key that carries no information +/// is a key the reader has to skip past. `query` says nothing on a generated +/// entry, and `flat` is implied by the sent generator. +void TestConfig::aGeneratedEntryWritesNoRedundantKeys() +{ + QTemporaryDir dir; + const QString path = writeIni(dir, twoAccountsWithSent()); + const QString queriesPath = writeQueries(dir, QStringLiteral(R"({ + "version": 1, + "queries": [ + { "name": "Sent", "generated": "sent", "pinned": true }, + { "name": "Inbox", "query": "tag:inbox", "pinned": true } + ] + })")); + + Config config; + config.load(path); + QVERIFY(config.saveSavedQueries()); + + QFile f(queriesPath); + QVERIFY(f.open(QIODevice::ReadOnly)); + const QJsonArray array = QJsonDocument::fromJson(f.readAll()) + .object() + .value(QStringLiteral("queries")) + .toArray(); + f.close(); + + const QJsonObject sent = array.at(0).toObject(); + QCOMPARE(sent.value(QStringLiteral("generated")).toString(), + QStringLiteral("sent")); + QVERIFY2(!sent.contains(QStringLiteral("query")), + "a generated entry has no query of its own to store"); + QVERIFY2(!sent.contains(QStringLiteral("flat")), + "the sent generator implies flat; storing it says nothing"); + + // The ordinary entry is untouched by any of that. + const QJsonObject inbox = array.at(1).toObject(); + QCOMPARE(inbox.value(QStringLiteral("query")).toString(), + QStringLiteral("tag:inbox")); + + // And it all still reads back the same. + Config reloaded; + reloaded.load(path); + QCOMPARE(reloaded.savedQueries().size(), 2); + QVERIFY(reloaded.savedQueries().at(0).isGenerated()); + QVERIFY2(reloaded.savedQueries().at(0).flat, + "flat must come back from the generator, not from the file"); +} + QTEST_MAIN(TestConfig) #include "test_config.moc" |
