Cancel pending style request when loading style JSON (#3709)
Co-authored-by: Tim Sylvester <tim@wetdogweather.com>
This commit is contained in:
@@ -29,6 +29,7 @@ add_library(
|
||||
${PROJECT_SOURCE_DIR}/test/src/mbgl/test/getrss.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/src/mbgl/test/sqlite3_test_fs.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/src/mbgl/test/stub_file_source.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/src/mbgl/test/delayed_file_source.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/src/mbgl/test/test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/src/mbgl/test/util.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/storage/asset_file_source.test.cpp
|
||||
|
||||
32
test/src/mbgl/test/delayed_file_source.cpp
Normal file
32
test/src/mbgl/test/delayed_file_source.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <mbgl/test/delayed_file_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
DelayedFileSource::AsyncRequestImpl::AsyncRequestImpl(DelayedFileSource& fs, Callback callback_)
|
||||
: fileSource(fs),
|
||||
callback(std::move(callback_)) {}
|
||||
|
||||
void DelayedFileSource::AsyncRequestImpl::respond() {
|
||||
if (callback) {
|
||||
callback(*fileSource.response);
|
||||
}
|
||||
}
|
||||
|
||||
DelayedFileSource::DelayedFileSource()
|
||||
: StubFileSource(StubFileSource::ResponseType::Synchronous) {}
|
||||
|
||||
std::unique_ptr<AsyncRequest> DelayedFileSource::request(const Resource&, Callback callback) {
|
||||
auto req = std::make_unique<AsyncRequestImpl>(*this, std::move(callback));
|
||||
pendingRequest = req.get();
|
||||
return req;
|
||||
}
|
||||
|
||||
void DelayedFileSource::respondToRequest(const std::string& data) {
|
||||
response = Response();
|
||||
response->data = std::make_shared<std::string>(data);
|
||||
if (pendingRequest) {
|
||||
pendingRequest->respond();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
43
test/src/mbgl/test/delayed_file_source.hpp
Normal file
43
test/src/mbgl/test/delayed_file_source.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/util/async_request.hpp>
|
||||
#include <mbgl/test/stub_file_source.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/*
|
||||
This is a file source that allows control of when a request is responded to.
|
||||
*/
|
||||
class DelayedFileSource : public StubFileSource {
|
||||
public:
|
||||
DelayedFileSource();
|
||||
~DelayedFileSource() override = default;
|
||||
|
||||
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
|
||||
|
||||
// Custom method to respond to pending request
|
||||
void respondToRequest(const std::string& data);
|
||||
|
||||
private:
|
||||
class AsyncRequestImpl : public AsyncRequest {
|
||||
public:
|
||||
using Callback = std::function<void(const Response&)>;
|
||||
|
||||
AsyncRequestImpl(DelayedFileSource& fs, Callback callback_);
|
||||
void respond();
|
||||
|
||||
private:
|
||||
DelayedFileSource& fileSource;
|
||||
Callback callback;
|
||||
};
|
||||
|
||||
friend class AsyncRequestImpl;
|
||||
std::optional<Response> response;
|
||||
AsyncRequestImpl* pendingRequest = nullptr;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/style/layers/line_layer.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/test/delayed_file_source.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -110,6 +111,38 @@ TEST(Style, RemoveSourceInUse) {
|
||||
EXPECT_EQ(log.count(logMessage), 1u);
|
||||
}
|
||||
|
||||
TEST(Style, LoadJSONCancelsPendingLoadURL) {
|
||||
util::RunLoop loop;
|
||||
|
||||
auto fileSource = std::make_shared<::DelayedFileSource>();
|
||||
Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}};
|
||||
|
||||
// Start loading a URL (this will be pending)
|
||||
auto url = "http://some-url";
|
||||
style.loadURL(url);
|
||||
|
||||
// Before the URL request completes, load JSON directly
|
||||
const std::string json = R"STYLE({
|
||||
"version": 8,
|
||||
"name": "Test Style",
|
||||
"sources": {},
|
||||
"layers": []
|
||||
})STYLE";
|
||||
style.loadJSON(json);
|
||||
|
||||
// The style should now be loaded with our JSON content
|
||||
ASSERT_EQ("Test Style", style.getName());
|
||||
ASSERT_EQ("", style.getURL());
|
||||
ASSERT_TRUE(style.getJSON().find("Test Style") != std::string::npos);
|
||||
|
||||
// Now respond to the original URL request - this should be ignored
|
||||
fileSource->respondToRequest(R"STYLE({"version":8,"name":"Streets"})STYLE");
|
||||
|
||||
// The style should still show our JSON content, not the URL content
|
||||
ASSERT_EQ("Test Style", style.getName());
|
||||
ASSERT_NE("Streets", style.getName());
|
||||
}
|
||||
|
||||
TEST(Style, SourceImplsOrder) {
|
||||
util::RunLoop loop;
|
||||
auto fileSource = std::make_shared<StubFileSource>();
|
||||
|
||||
Reference in New Issue
Block a user