Files
qelectrotech-source-mirror/tests/qttest/tst_changedondisk.cpp
T
ispyisail 89c3979957 Fix Save writing a .qetz beside an opened .qet: keep the .qet
A project opened from a .qet was saved as a .qetz beside it, with a
notice, and the .qet left as it was: a project kept in git did not stay
a .qet. Save now writes the format the project was opened in; only Save
As changes it (scorpio810, discussion #1512). A .qetz is saved as a
.qetz as before.

The save-beside path goes: the flag set on opening, the .qetz path made
from the .qet's, write()'s switch to it and back on failure, and the
notice and replace question in ProjectView::doSave().

tst_resaveunchanged::qetSavedAsQetzBeside becomes qetSavedAsQet: Save of
an opened .qet writes no .qetz and the .qet holds what a plain save of
it holds (it fails without the fix: a .qetz is written beside).
tst_changedondisk makes its .qetz with Save As, as Save no longer does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:56:22 +13:00

108 lines
4.2 KiB
C++

// SPDX-License-Identifier: GPL-2.0-or-later
#include <QtTest>
#include <QFile>
#include <QProcess>
#include <QProcessEnvironment>
#include <QTemporaryDir>
// Saving a project replaced the file whatever had happened to it since it was
// opened: another user's save, or another program's, was lost without a word.
// QETProject now remembers the file as it read or wrote it and write() refuses
// when the file on disk is no longer that one. Driven through the real
// binary's --run: qet.save(<the project's own path>) writes the file behind
// the open project without updating what it remembers, which is exactly "someone
// else saved"; qet.save('') is the project's own save.
class tst_changedondisk : public QObject
{
Q_OBJECT
QTemporaryDir m_dir;
QString m_project; // a .qetz made from examples/741.qet
QString run(const QString &script, const QString &project, bool overwrite = false)
{
const QString path = m_dir.filePath(QStringLiteral("probe.js"));
const QString home = m_dir.filePath(QStringLiteral("home"));
QDir().mkpath(home);
QFile f(path);
if (!f.open(QIODevice::WriteOnly)) return QString();
f.write(script.toUtf8());
f.close();
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("offscreen"));
env.insert(QStringLiteral("QET_ENABLE_SCRIPTING"), QStringLiteral("1"));
env.insert(QStringLiteral("HOME"), home);
env.insert(QStringLiteral("XDG_CONFIG_HOME"), home + QStringLiteral("/config"));
env.insert(QStringLiteral("XDG_DATA_HOME"), home + QStringLiteral("/data"));
env.insert(QStringLiteral("TMPDIR"), m_dir.path());
env.remove(QStringLiteral("QET_OVERWRITE_CHANGED"));
if (overwrite)
env.insert(QStringLiteral("QET_OVERWRITE_CHANGED"), QStringLiteral("1"));
QProcess proc;
proc.setProcessEnvironment(env);
proc.start(QStringLiteral(QET_TEST_BINARY_PATH),
{QStringLiteral("--run"), path, project});
if (!proc.waitForFinished(120000)) return QString();
return QString::fromUtf8(proc.readAllStandardOutput() + proc.readAllStandardError());
}
private slots:
void initTestCase()
{
QVERIFY(m_dir.isValid());
QVERIFY(QFile::exists(QStringLiteral(QET_TEST_BINARY_PATH)));
const QString qet = m_dir.filePath(QStringLiteral("p.qet"));
QVERIFY(QFile::copy(QStringLiteral(QET_EXAMPLES_DIR "/741.qet"), qet));
// the .qet saved as a .qetz is the project below
m_project = m_dir.filePath(QStringLiteral("p.qetz"));
const QString out = run(QStringLiteral("qet.log('R ' + qet.save('%1'));\n").arg(m_project), qet);
QVERIFY2(out.contains(QStringLiteral("R true")), qPrintable(out));
QVERIFY(QFile::exists(m_project));
}
void unchangedFileSaves()
{
const QString out = run(QStringLiteral(
"qet.log('R1 ' + qet.save(''));\nqet.log('R2 ' + qet.save(''));\n"), m_project);
QVERIFY2(out.contains(QStringLiteral("R1 true")), qPrintable(out));
// the project's own save updates what it remembers: a second one is no change
QVERIFY2(out.contains(QStringLiteral("R2 true")), qPrintable(out));
}
void changedFileIsNotOverwritten()
{
const QString script = QStringLiteral(
"qet.save(%1);\nqet.log('R ' + qet.save(''));\n")
.arg(QStringLiteral("'") + m_project + QStringLiteral("'"));
const QString out = run(script, m_project);
QVERIFY2(out.contains(QStringLiteral("R false")), qPrintable(out));
QVERIFY2(out.contains(QStringLiteral("changed the file on disk")), qPrintable(out));
}
void overrideOverwrites()
{
const QString script = QStringLiteral(
"qet.save(%1);\nqet.log('R ' + qet.save(''));\n")
.arg(QStringLiteral("'") + m_project + QStringLiteral("'"));
const QString out = run(script, m_project, true);
QVERIFY2(out.contains(QStringLiteral("R true")), qPrintable(out));
}
void saveAsTargetIsNotAConflict()
{
const QString other = m_dir.filePath(QStringLiteral("other.qetz"));
const QString script = QStringLiteral(
"qet.log('R1 ' + qet.save(%1));\nqet.log('R2 ' + qet.save(%1));\n")
.arg(QStringLiteral("'") + other + QStringLiteral("'"));
const QString out = run(script, m_project);
QVERIFY2(out.contains(QStringLiteral("R1 true")), qPrintable(out));
QVERIFY2(out.contains(QStringLiteral("R2 true")), qPrintable(out));
}
};
QTEST_APPLESS_MAIN(tst_changedondisk)
#include "tst_changedondisk.moc"