summaryrefslogtreecommitdiff
path: root/test/fixtures/mock_file_source.cpp
blob: 078271a4228000c167abe7d94e6fa1cfd034e8b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include "mock_file_source.hpp"
#include <mbgl/util/io.hpp>
#include <mbgl/util/chrono.hpp>

namespace mbgl {

class MockFileRequest : public FileRequest {
public:
    MockFileRequest(MockFileSource& fileSource_)
        : fileSource(fileSource_) {
    }

    ~MockFileRequest() {
        fileSource.pending.erase(this);
    }

    MockFileSource& fileSource;
};

MockFileSource::MockFileSource(Type type_, const std::string& match_)
    : type(type_), match(match_) {
    timer.start(Milliseconds(10), Milliseconds(10), [this] {
        // Explicit move to avoid iterator invalidation if ~MockFileRequest gets called within the loop.
        auto pending_ = std::move(pending);
        for (auto& pair : pending_) {
            respond(pair.second.first, pair.second.second);
        }
    });
}

MockFileSource::~MockFileSource() {
    timer.stop();
}

void MockFileSource::respond(Resource resource, Callback callback) const {
    if (type == Type::Success || resource.url.find(match) == std::string::npos) {
        Response res;
        try {
            res.data = std::make_shared<const std::string>(util::read_file(resource.url));
        } catch (const std::exception& err) {
            res.error = std::make_unique<Response::Error>(Response::Error::Reason::Other, err.what());
        }
        callback(res);
    } else if (type == Type::RequestFail) {
        Response res;
        res.error = std::make_unique<Response::Error>(Response::Error::Reason::Other, "Failed by the test case");
        callback(res);
    } else if (type == Type::RequestWithCorruptedData) {
        Response res;
        auto data = std::make_shared<std::string>(util::read_file(resource.url));
        data->insert(0, "CORRUPTED");
        res.data = std::move(data);
        callback(res);
    }
}

std::unique_ptr<FileRequest> MockFileSource::request(const Resource& resource, Callback callback) {
    auto req = std::make_unique<MockFileRequest>(*this);

    pending.emplace(req.get(), std::make_pair(resource, callback));

    if (requestEnqueuedCallback && resource.url.find(match) != std::string::npos) {
        requestEnqueuedCallback();
    }

    return std::move(req);
}

} // namespace mbgl