feat/dataset-detail-chart #5

Merged
gaozheng merged 74 commits from feat/dataset-detail-chart into main 2026-06-13 17:30:37 +08:00
3 changed files with 40 additions and 0 deletions
Showing only changes of commit 350f46060d - Show all commits

View File

@ -6,6 +6,11 @@ namespace geopro::controller {
DatasetDetailController::DatasetDetailController(data::IAsyncDatasetRepository& repo, QObject* parent) DatasetDetailController::DatasetDetailController(data::IAsyncDatasetRepository& repo, QObject* parent)
: QObject(parent), repo_(repo) {} : QObject(parent), repo_(repo) {}
DatasetDetailController::~DatasetDetailController() {
if (chartLoad_) chartLoad_->abort(); // 退出契约abort 在飞句柄,不依赖外部析构顺序兜底
if (gridLoad_) gridLoad_->abort();
}
void DatasetDetailController::openDataset(const QString& dsId, const QString& ddCode) { void DatasetDetailController::openDataset(const QString& dsId, const QString& ddCode) {
if (ddCode != QLatin1String("dd_inversion_data")) { // 首版仅支持 ERT 反演 if (ddCode != QLatin1String("dd_inversion_data")) { // 首版仅支持 ERT 反演
emit loadFailed(dsId, QStringLiteral("暂不支持该数据类型的预览")); emit loadFailed(dsId, QStringLiteral("暂不支持该数据类型的预览"));

View File

@ -33,6 +33,7 @@ public:
}; };
explicit DatasetDetailController(data::IAsyncDatasetRepository& repo, QObject* parent = nullptr); explicit DatasetDetailController(data::IAsyncDatasetRepository& repo, QObject* parent = nullptr);
~DatasetDetailController() override; // 退出契约(spec §7)abort 在飞句柄,避免迟到信号打到已析构 this
public slots: public slots:
void openDataset(const QString& dsId, const QString& ddCode); void openDataset(const QString& dsId, const QString& ddCode);
void focusDataset(const QString& dsId); void focusDataset(const QString& dsId);

View File

@ -17,6 +17,7 @@ struct StubGridLoad : data::GridLoad {
bool aborted = false; bool aborted = false;
void abort() override { aborted = true; } void abort() override { aborted = true; }
void fireDone() { emit done(data::GridParts{}); } void fireDone() { emit done(data::GridParts{}); }
void fireFailed() { emit failed(QStringLiteral("x")); }
}; };
struct StubAsyncRepo : data::IAsyncDatasetRepository { struct StubAsyncRepo : data::IAsyncDatasetRepository {
StubChartLoad* lastChart = nullptr; StubChartLoad* lastChart = nullptr;
@ -79,3 +80,36 @@ TEST(DatasetDetailController, DropsLateSignalFromAbortedLoad) {
b->fireDone(); // 当前句柄 → 正常 b->fireDone(); // 当前句柄 → 正常
EXPECT_EQ(spy.count(), 1); EXPECT_EQ(spy.count(), 1);
} }
TEST(DatasetDetailController, EmitsGridReadyOnDone) {
StubAsyncRepo repo;
controller::DatasetDetailController c(repo);
QSignalSpy spy(&c, &controller::DatasetDetailController::gridReady);
c.loadGridData("ds1", "dd_inversion_data");
repo.lastGrid->fireDone();
EXPECT_EQ(spy.count(), 1);
}
TEST(DatasetDetailController, EmitsLoadFailedOnGridFailed) {
StubAsyncRepo repo;
controller::DatasetDetailController c(repo);
QSignalSpy spy(&c, &controller::DatasetDetailController::loadFailed);
c.loadGridData("ds1", "dd_inversion_data");
repo.lastGrid->fireFailed();
EXPECT_EQ(spy.count(), 1);
}
TEST(DatasetDetailController, DropsLateGridSignalFromAbortedLoad) {
StubAsyncRepo repo;
controller::DatasetDetailController c(repo);
QSignalSpy spy(&c, &controller::DatasetDetailController::gridReady);
c.loadGridData("dsA", "dd_inversion_data");
StubGridLoad* a = repo.lastGrid;
c.loadGridData("dsB", "dd_inversion_data"); // 替换 → 旧句柄被 abort
StubGridLoad* b = repo.lastGrid;
EXPECT_TRUE(a->aborted);
a->fireDone(); // 旧句柄迟到 → 身份比对丢弃
EXPECT_EQ(spy.count(), 0);
b->fireDone(); // 当前句柄 → 正常
EXPECT_EQ(spy.count(), 1);
}