72 lines
2.8 KiB
C++
72 lines
2.8 KiB
C++
#include <gtest/gtest.h>
|
||
#include <stdexcept>
|
||
#include <QSignalSpy>
|
||
#include <QVariant>
|
||
#include "api/DatasetLoadHandles.hpp"
|
||
#include "model/detail/DetailPayloads.hpp"
|
||
#include "net/FakeApiCall.hpp"
|
||
|
||
using namespace geopro::data;
|
||
using geopro::net::ApiBatch;
|
||
using geopro::net::ApiResponse;
|
||
using geopro::net::test::FakeApiCall;
|
||
using geopro::core::ScatterPayload;
|
||
|
||
namespace {
|
||
ApiResponse ok() { ApiResponse r; r.code = 200; r.httpStatus = 200; return r; }
|
||
ApiResponse bad() { ApiResponse r; r.code = 500; r.httpStatus = 200; r.msg = QStringLiteral("boom"); return r; }
|
||
auto isFailure = [](const ApiResponse& r) { return r.code != 200 || !r.rawError.isEmpty(); };
|
||
}
|
||
|
||
// ── 通用详情句柄 ApiDetailLoad(tab 引擎):done(QVariant) / failed / abort 闸门 ──
|
||
|
||
TEST(DatasetLoadHandles, DetailLoadEmitsDoneWithPayloadOnSuccess) {
|
||
auto* a = new FakeApiCall;
|
||
auto* b = new FakeApiCall;
|
||
auto* batch = new ApiBatch({a, b}, isFailure);
|
||
auto* load = new ApiDetailLoad(batch, [](const QList<ApiResponse>& resps) {
|
||
ScatterPayload p;
|
||
p.scatter.v = std::vector<double>(static_cast<size_t>(resps.size()), 0.0); // 携带可校验状态
|
||
return QVariant::fromValue(p);
|
||
});
|
||
QSignalSpy doneSpy(load, &DetailLoad::done);
|
||
a->fire(ok());
|
||
b->fire(ok());
|
||
ASSERT_EQ(doneSpy.count(), 1);
|
||
QVariant payload = doneSpy.takeFirst().at(0).value<QVariant>();
|
||
ASSERT_TRUE(payload.canConvert<ScatterPayload>());
|
||
EXPECT_EQ(payload.value<ScatterPayload>().scatter.v.size(), 2u); // round-trip 还原字段
|
||
}
|
||
|
||
TEST(DatasetLoadHandles, DetailLoadEmitsFailedOnBatchFailure) {
|
||
auto* a = new FakeApiCall;
|
||
auto* batch = new ApiBatch({a}, isFailure);
|
||
auto* load = new ApiDetailLoad(batch, [](const QList<ApiResponse>&) { return QVariant{}; });
|
||
QSignalSpy failSpy(load, &DetailLoad::failed);
|
||
a->fire(bad());
|
||
EXPECT_EQ(failSpy.count(), 1);
|
||
}
|
||
|
||
TEST(DatasetLoadHandles, DetailLoadEmitsFailedWhenParseThrows) {
|
||
auto* a = new FakeApiCall;
|
||
auto* batch = new ApiBatch({a}, isFailure);
|
||
auto* load = new ApiDetailLoad(batch, [](const QList<ApiResponse>&) -> QVariant {
|
||
throw std::runtime_error("parse boom");
|
||
});
|
||
QSignalSpy doneSpy(load, &DetailLoad::done);
|
||
QSignalSpy failSpy(load, &DetailLoad::failed);
|
||
a->fire(ok()); // batch 成功 → parse 抛 → failed(done 已移出 try)
|
||
EXPECT_EQ(doneSpy.count(), 0);
|
||
EXPECT_EQ(failSpy.count(), 1);
|
||
}
|
||
|
||
TEST(DatasetLoadHandles, DetailLoadAbortSuppressesLateDone) {
|
||
auto* a = new FakeApiCall;
|
||
auto* batch = new ApiBatch({a}, isFailure);
|
||
auto* load = new ApiDetailLoad(batch, [](const QList<ApiResponse>&) { return QVariant{}; });
|
||
QSignalSpy doneSpy(load, &DetailLoad::done);
|
||
load->abort();
|
||
a->fire(ok()); // 迟到
|
||
EXPECT_EQ(doneSpy.count(), 0); // 双闸门
|
||
}
|