rearrange tests and add storage tests
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@
|
||||
/config-ios.gypi
|
||||
/config-android.gypi
|
||||
/build
|
||||
/test/node_modules
|
||||
/include/mbgl/shader/shaders.hpp
|
||||
/src/shader/shaders_gl.cpp
|
||||
/src/shader/shaders_gles2.cpp
|
||||
|
||||
8
Makefile
8
Makefile
@@ -105,10 +105,12 @@ android:
|
||||
|
||||
test: build/test/Makefile
|
||||
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) test
|
||||
./scripts/run_tests.sh
|
||||
|
||||
test_%: build/test/Makefile
|
||||
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) $*
|
||||
(cd build/$(BUILDTYPE) && exec ./test_$*)
|
||||
|
||||
test-%: build/test/Makefile
|
||||
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) test
|
||||
build/$(BUILDTYPE)/test --gtest_filter=$*
|
||||
|
||||
# build Mac OS X project for Xcode
|
||||
xtest: build/test/test.xcodeproj
|
||||
|
||||
@@ -52,9 +52,14 @@ void log_gl_string(GLenum name, const char *label) {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase() {
|
||||
return mbgl::android::cachePath + "/mbgl-cache.db";
|
||||
}
|
||||
|
||||
NativeMapView::NativeMapView(JNIEnv *env, jobject obj_)
|
||||
: mbgl::View(*this),
|
||||
fileSource(mbgl::platform::defaultCacheDatabase()),
|
||||
fileSource(defaultCacheDatabase()),
|
||||
map(*this, fileSource) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView");
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'../platform/android/cache_database_data.cpp',
|
||||
'../platform/android/log_android.cpp',
|
||||
'../platform/android/asset_request_libzip.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'../platform/default/cache_database_tmp.cpp',
|
||||
'../platform/default/shader_cache_tmp.cpp',
|
||||
'../platform/default/log_stderr.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
'../platform/default/http_request_curl.cpp',
|
||||
'../platform/default/asset_request_libuv.cpp',
|
||||
'../platform/default/http_request_baton_curl.cpp',
|
||||
'../platform/default/application_root.cpp',
|
||||
'../platform/default/image.cpp',
|
||||
'../platform/default/image_reader.cpp',
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
'version',
|
||||
],
|
||||
'sources': [
|
||||
'../platform/osx/cache_database_application_support.mm',
|
||||
'../platform/osx/shader_cache_application_support.mm',
|
||||
'../platform/darwin/log_nslog.mm',
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_cocoa.mm',
|
||||
@@ -33,6 +33,7 @@
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [
|
||||
'-framework Foundation',
|
||||
'-framework ImageIO',
|
||||
'-framework CoreServices',
|
||||
],
|
||||
|
||||
@@ -17,8 +17,8 @@ std::string uppercase(const std::string &string);
|
||||
// Lowercase a string, potentially using platform-specific routines.
|
||||
std::string lowercase(const std::string &string);
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase();
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string defaultShaderCache();
|
||||
|
||||
std::string applicationRoot();
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ int main(int argc, char *argv[]) {
|
||||
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||
|
||||
view = new GLFWView();
|
||||
mbgl::CachingHTTPFileSource fileSource(mbgl::platform::defaultCacheDatabase());
|
||||
mbgl::CachingHTTPFileSource fileSource();
|
||||
mbgl::Map map(*view, fileSource);
|
||||
|
||||
// Load settings
|
||||
|
||||
@@ -72,12 +72,35 @@
|
||||
}
|
||||
@end
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase() {
|
||||
NSArray *paths =
|
||||
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0) {
|
||||
// Disable the cache if we don't have a location to write.
|
||||
return "";
|
||||
}
|
||||
|
||||
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Mapbox GL"];
|
||||
|
||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:path
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:nil]) {
|
||||
// Disable the cache if we couldn't create the directory.
|
||||
return "";
|
||||
}
|
||||
|
||||
return [[path stringByAppendingPathComponent:@"cache.db"] UTF8String];
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
mbgl::Log::Set<mbgl::NSLogBackend>();
|
||||
|
||||
GLFWView view;
|
||||
|
||||
mbgl::SQLiteCache cache(mbgl::platform::defaultCacheDatabase());
|
||||
mbgl::SQLiteCache cache(defaultCacheDatabase());
|
||||
mbgl::DefaultFileSource fileSource(&cache);
|
||||
mbgl::Map map(view, fileSource);
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/android/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase() {
|
||||
return mbgl::android::cachePath + "/mbgl-cache.db";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase() {
|
||||
NSArray *paths =
|
||||
NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0) {
|
||||
// Disable the cache if we don't have a location to write.
|
||||
return "";
|
||||
}
|
||||
|
||||
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Mapbox GL"];
|
||||
|
||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:path
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:nil]) {
|
||||
// Disable the cache if we couldn't create the directory.
|
||||
return "";
|
||||
}
|
||||
|
||||
return [[path stringByAppendingPathComponent:@"cache.db"] UTF8String];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
cd build/${BUILDTYPE:-Release}
|
||||
|
||||
for TEST in ./test_* ; do
|
||||
for TEST in build/${BUILDTYPE:-Release}/test* ; do
|
||||
# allow writing core files
|
||||
ulimit -c unlimited -S
|
||||
echo 'ulimit -c: '`ulimit -c`
|
||||
echo '/proc/sys/kernel/core_pattern: '`cat /proc/sys/kernel/core_pattern`
|
||||
if [ -f /proc/sys/kernel/core_pattern ]; then
|
||||
echo '/proc/sys/kernel/core_pattern: '`cat /proc/sys/kernel/core_pattern`
|
||||
fi
|
||||
|
||||
if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then
|
||||
sysctl kernel.core_pattern
|
||||
|
||||
@@ -92,7 +92,6 @@ void Sprite::load(FileSource& fileSource) {
|
||||
|
||||
void Sprite::complete() {
|
||||
if (loadedImage && loadedJSON) {
|
||||
Log::Info(Event::Sprite, "loaded %s", spriteURL.c_str());
|
||||
promise.set_value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/map/vector_tile.hpp>
|
||||
#include <mbgl/style/filter_expression.hpp>
|
||||
|
||||
47
test/fixtures/fixture_log.cpp
vendored
47
test/fixtures/fixture_log.cpp
vendored
@@ -1,47 +0,0 @@
|
||||
#include "fixture_log.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
FixtureLogBackend::~FixtureLogBackend() {
|
||||
std::cerr << unchecked();
|
||||
}
|
||||
|
||||
size_t FixtureLogBackend::count(const LogMessage &message) const {
|
||||
size_t message_count = 0;
|
||||
for (const LogMessage &msg : messages) {
|
||||
if (msg == message) {
|
||||
message_count++;
|
||||
msg.checked = true;
|
||||
}
|
||||
}
|
||||
return message_count;
|
||||
}
|
||||
|
||||
std::vector<FixtureLogBackend::LogMessage> FixtureLogBackend::unchecked() const {
|
||||
std::vector<LogMessage> unchecked_messages;
|
||||
for (const LogMessage &msg : messages) {
|
||||
if (!msg.checked) {
|
||||
unchecked_messages.push_back(msg);
|
||||
msg.checked = true;
|
||||
}
|
||||
}
|
||||
return unchecked_messages;
|
||||
}
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLogBackend::LogMessage>& messages) {
|
||||
for (const FixtureLogBackend::LogMessage &message : messages) {
|
||||
os << "- " << message;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const FixtureLogBackend::LogMessage& message) {
|
||||
os << "[\"" << message.severity.get() << "\", \"" << message.event.get() << "\"";
|
||||
if (message.code) os << ", " << message.code.get();
|
||||
if (message.msg) os << ", \"" << message.msg.get() << "\"";
|
||||
return os << "]" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
59
test/fixtures/fixture_log.hpp
vendored
59
test/fixtures/fixture_log.hpp
vendored
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -37,13 +39,13 @@ public:
|
||||
mutable bool checked = false;
|
||||
};
|
||||
|
||||
~FixtureLogBackend();
|
||||
inline ~FixtureLogBackend();
|
||||
|
||||
void record(EventSeverity severity, Event event, const std::string &msg) {
|
||||
inline void record(EventSeverity severity, Event event, const std::string &msg) {
|
||||
messages.emplace_back(severity, event, msg);
|
||||
}
|
||||
|
||||
void record(EventSeverity severity, Event event, const char* format, ...) {
|
||||
inline void record(EventSeverity severity, Event event, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
const size_t len = vsnprintf(NULL, 0, format, args);
|
||||
@@ -55,24 +57,63 @@ public:
|
||||
messages.emplace_back(severity, event, std::string { buffer.get(), len });
|
||||
}
|
||||
|
||||
void record(EventSeverity severity, Event event, int64_t code) {
|
||||
inline void record(EventSeverity severity, Event event, int64_t code) {
|
||||
messages.emplace_back(severity, event, code);
|
||||
}
|
||||
|
||||
void record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
|
||||
inline void record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
|
||||
messages.emplace_back(severity, event, code, msg);
|
||||
}
|
||||
|
||||
size_t count(const LogMessage &message) const;
|
||||
std::vector<LogMessage> unchecked() const;
|
||||
inline size_t count(const LogMessage &message) const;
|
||||
inline std::vector<LogMessage> unchecked() const;
|
||||
|
||||
public:
|
||||
std::vector<LogMessage> messages;
|
||||
};
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLogBackend::LogMessage>& messages);
|
||||
::std::ostream& operator<<(::std::ostream& os, const FixtureLogBackend::LogMessage& message);
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLogBackend::LogMessage>& messages);
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, const FixtureLogBackend::LogMessage& message);
|
||||
|
||||
FixtureLogBackend::~FixtureLogBackend() {
|
||||
std::cerr << unchecked();
|
||||
}
|
||||
|
||||
size_t FixtureLogBackend::count(const LogMessage &message) const {
|
||||
size_t message_count = 0;
|
||||
for (const LogMessage &msg : messages) {
|
||||
if (msg == message) {
|
||||
message_count++;
|
||||
msg.checked = true;
|
||||
}
|
||||
}
|
||||
return message_count;
|
||||
}
|
||||
|
||||
std::vector<FixtureLogBackend::LogMessage> FixtureLogBackend::unchecked() const {
|
||||
std::vector<LogMessage> unchecked_messages;
|
||||
for (const LogMessage &msg : messages) {
|
||||
if (!msg.checked) {
|
||||
unchecked_messages.push_back(msg);
|
||||
msg.checked = true;
|
||||
}
|
||||
}
|
||||
return unchecked_messages;
|
||||
}
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLogBackend::LogMessage>& messages) {
|
||||
for (const FixtureLogBackend::LogMessage &message : messages) {
|
||||
os << "- " << message;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const FixtureLogBackend::LogMessage& message) {
|
||||
os << "[\"" << message.severity.get() << "\", \"" << message.event.get() << "\"";
|
||||
if (message.code) os << ", " << message.code.get();
|
||||
if (message.msg) os << ", \"" << message.msg.get() << "\"";
|
||||
return os << "]" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
51
test/fixtures/server_environment.hpp
vendored
Normal file
51
test/fixtures/server_environment.hpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef MBGL_TEST_FIXTURES_SERVER_ENVIRONMENT
|
||||
#define MBGL_TEST_FIXTURES_SERVER_ENVIRONMENT
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
#include <libgen.h>
|
||||
|
||||
class ServerEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
inline ServerEnvironment(const std::string &executable);
|
||||
inline virtual void SetUp();
|
||||
inline virtual void TearDown();
|
||||
|
||||
private:
|
||||
const std::string executable;
|
||||
const std::string parent_pid = std::to_string(getpid());
|
||||
pid_t pid = 0;
|
||||
};
|
||||
|
||||
ServerEnvironment::ServerEnvironment(const std::string &executable_) : executable(executable_) {}
|
||||
|
||||
void ServerEnvironment::SetUp() {
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
throw std::runtime_error("Cannot create server process");
|
||||
} else if (pid == 0) {
|
||||
char *arg[] = {
|
||||
const_cast<char *>(executable.c_str()),
|
||||
const_cast<char *>(parent_pid.c_str()),
|
||||
nullptr
|
||||
};
|
||||
int ret = execv(executable.c_str(), arg);
|
||||
// This call should not return. In case execve failed, we exit anyway.
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to start server: %s\n", strerror(errno));
|
||||
}
|
||||
exit(0);
|
||||
} else {
|
||||
// Wait until the server process sends SIGCONT.
|
||||
raise(SIGSTOP);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerEnvironment::TearDown() {
|
||||
ASSERT_TRUE(pid);
|
||||
kill(pid, SIGHUP);
|
||||
}
|
||||
|
||||
#endif
|
||||
0
test/fixtures/storage/empty
vendored
Normal file
0
test/fixtures/storage/empty
vendored
Normal file
@@ -1,4 +1,5 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/server_environment.hpp"
|
||||
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
@@ -13,81 +14,9 @@
|
||||
#include <mbgl/platform/default/headless_display.hpp>
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
#include "./fixtures/fixture_log.hpp"
|
||||
#include "../fixtures/fixture_log.hpp"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
#include <libgen.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
std::string base_directory;
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
std::string defaultCacheDatabase() {
|
||||
// Disables the cache.
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ServerEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
throw std::runtime_error("Cannot create web server");
|
||||
} else if (pid == 0) {
|
||||
#ifdef __linux__
|
||||
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
||||
#endif
|
||||
const auto executable = base_directory + "bin/server.py";
|
||||
const char *port = "2900";
|
||||
char *arg[] = { const_cast<char *>(executable.c_str()), const_cast<char *>(port), nullptr };
|
||||
int ret = execv(executable.c_str(), arg);
|
||||
// This call should not return. In case execve failed, we exit anyway.
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to start server: %s\n", strerror(errno));
|
||||
}
|
||||
exit(0);
|
||||
} else {
|
||||
display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
}
|
||||
}
|
||||
virtual void TearDown() {
|
||||
ASSERT_TRUE(pid);
|
||||
kill(pid, SIGHUP);
|
||||
}
|
||||
|
||||
std::shared_ptr<mbgl::HeadlessDisplay> display;
|
||||
|
||||
private:
|
||||
pid_t pid = 0;
|
||||
};
|
||||
|
||||
|
||||
ServerEnvironment* env = nullptr;
|
||||
|
||||
|
||||
GTEST_API_ int main(int argc, char *argv[]) {
|
||||
// Note: glibc's dirname() **modifies** the argument and can't handle static strings.
|
||||
std::string file { __FILE__ }; file = dirname(const_cast<char *>(file.c_str()));
|
||||
if (file[0] == '/') {
|
||||
// If __FILE__ is an absolute path, we don't have to guess from the argv 0.
|
||||
base_directory = file + "/suite/";
|
||||
} else {
|
||||
std::string argv0 { argv[0] }; argv0 = dirname(const_cast<char *>(argv0.c_str()));
|
||||
base_directory = argv0 + "/" + file + "/suite/";
|
||||
}
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
env = new ServerEnvironment();
|
||||
::testing::AddGlobalTestEnvironment(env);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
std::shared_ptr<mbgl::HeadlessDisplay> display;
|
||||
|
||||
void rewriteLocalScheme(rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator) {
|
||||
ASSERT_TRUE(value.IsString());
|
||||
@@ -105,8 +34,8 @@ TEST_P(HeadlessTest, render) {
|
||||
|
||||
const std::string& base = GetParam();
|
||||
|
||||
std::string style = util::read_file(base_directory + "tests/" + base + "/style.json");
|
||||
std::string info = util::read_file(base_directory + "tests/" + base + "/info.json");
|
||||
std::string style = util::read_file("test/suite/tests/" + base + "/style.json");
|
||||
std::string info = util::read_file("test/suite/tests/" + base + "/info.json");
|
||||
|
||||
// Parse style.
|
||||
rapidjson::Document styleDoc;
|
||||
@@ -169,7 +98,7 @@ TEST_P(HeadlessTest, render) {
|
||||
|
||||
if (value.HasMember("center")) ASSERT_TRUE(value["center"].IsArray());
|
||||
|
||||
const std::string actual_image = base_directory + "tests/" + base + "/" + name + "/actual.png";
|
||||
const std::string actual_image = "test/suite/tests/" + base + "/" + name + "/actual.png";
|
||||
|
||||
const double zoom = value.HasMember("zoom") ? value["zoom"].GetDouble() : 0;
|
||||
const double bearing = value.HasMember("bearing") ? value["bearing"].GetDouble() : 0;
|
||||
@@ -190,19 +119,22 @@ TEST_P(HeadlessTest, render) {
|
||||
}
|
||||
}
|
||||
|
||||
HeadlessView view(env->display);
|
||||
if (!display) {
|
||||
display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
}
|
||||
|
||||
HeadlessView view(display);
|
||||
mbgl::DefaultFileSource fileSource(nullptr);
|
||||
Map map(view, fileSource);
|
||||
|
||||
map.setClasses(classes);
|
||||
map.setStyleJSON(style, base_directory);
|
||||
map.setStyleJSON(style, "test/suite");
|
||||
|
||||
view.resize(width, height, pixelRatio);
|
||||
map.resize(width, height, pixelRatio);
|
||||
map.setLonLatZoom(longitude, latitude, zoom);
|
||||
map.setBearing(bearing);
|
||||
|
||||
|
||||
// Run the loop. It will terminate when we don't have any further listeners.
|
||||
map.run();
|
||||
|
||||
@@ -219,19 +151,17 @@ TEST_P(HeadlessTest, render) {
|
||||
INSTANTIATE_TEST_CASE_P(Headless, HeadlessTest, ::testing::ValuesIn([] {
|
||||
std::vector<std::string> names;
|
||||
|
||||
DIR *dir = opendir((base_directory + "tests").c_str());
|
||||
if (dir == nullptr) {
|
||||
return names;
|
||||
}
|
||||
|
||||
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
|
||||
const std::string name = dp->d_name;
|
||||
if (name != "index.html" && !(name.size() >= 1 && name[0] == '.')) {
|
||||
names.push_back(name);
|
||||
DIR *dir = opendir("test/suite/tests");
|
||||
if (dir != nullptr) {
|
||||
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
|
||||
const std::string name = dp->d_name;
|
||||
if (name != "index.html" && !(name.size() >= 1 && name[0] == '.')) {
|
||||
names.push_back(name);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
EXPECT_GT(names.size(), 0ul);
|
||||
return names;
|
||||
}()));
|
||||
17
test/headless/headless.gypi
Normal file
17
test/headless/headless.gypi
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'test_headless',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'test_base',
|
||||
'../mapboxgl.gyp:mbgl-core',
|
||||
'../mapboxgl.gyp:mbgl-<(platform)',
|
||||
'../mapboxgl.gyp:mbgl-headless',
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
],
|
||||
'sources': [
|
||||
'headless.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
19
test/headless/server.js
Executable file
19
test/headless/server.js
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env node
|
||||
/* jshint node: true */
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
|
||||
app.use(express.static('test/suite'));
|
||||
|
||||
var server = app.listen(2900, function () {
|
||||
var host = server.address().address;
|
||||
var port = server.address().port;
|
||||
console.log('Test server listening at http://%s:%s', host, port);
|
||||
|
||||
if (process.argv[2]) {
|
||||
// Allow the test to continue running.
|
||||
process.kill(+process.argv[2], 'SIGCONT');
|
||||
}
|
||||
});
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "util.hpp"
|
||||
#include "fixtures/server_environment.hpp"
|
||||
|
||||
GTEST_API_ int main(int argc, char *argv[]) {
|
||||
testing::AddGlobalTestEnvironment(new ServerEnvironment("test/headless/server.js"));
|
||||
testing::AddGlobalTestEnvironment(new ServerEnvironment("test/storage/server.js"));
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
103
test/miscellaneous/comparisons.cpp
Normal file
103
test/miscellaneous/comparisons.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/map/vector_tile.hpp>
|
||||
#include <mbgl/style/filter_expression.hpp>
|
||||
#include <mbgl/style/filter_expression_private.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
typedef std::multimap<std::string, mbgl::Value> Properties;
|
||||
|
||||
class Extractor {
|
||||
public:
|
||||
inline Extractor(const Properties& properties_, FeatureType type_)
|
||||
: properties(properties_)
|
||||
, type(type_)
|
||||
{}
|
||||
|
||||
mapbox::util::optional<Value> getValue(const std::string &key) const {
|
||||
if (key == "$type")
|
||||
return Value(uint64_t(type));
|
||||
auto it = properties.find(key);
|
||||
if (it == properties.end())
|
||||
return mapbox::util::optional<Value>();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
FeatureType getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
private:
|
||||
const Properties properties;
|
||||
FeatureType type;
|
||||
};
|
||||
|
||||
FilterExpression parse(const char * expression) {
|
||||
rapidjson::Document doc;
|
||||
doc.Parse<0>(expression);
|
||||
return parseFilterExpression(doc);
|
||||
}
|
||||
|
||||
bool evaluate(const FilterExpression& expression, const Properties& properties, FeatureType type = FeatureType::Unknown) {
|
||||
return mbgl::evaluate(expression, Extractor(properties, type));
|
||||
}
|
||||
|
||||
TEST(FilterComparison, EqualsString) {
|
||||
FilterExpression f = parse("[\"==\", \"foo\", \"bar\"]");
|
||||
ASSERT_TRUE(evaluate(f, {{ "foo", std::string("bar") }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", std::string("baz") }}));
|
||||
};
|
||||
|
||||
TEST(FilterComparison, EqualsNumber) {
|
||||
FilterExpression f = parse("[\"==\", \"foo\", 0]");
|
||||
ASSERT_TRUE(evaluate(f, {{ "foo", int64_t(0) }}));
|
||||
ASSERT_TRUE(evaluate(f, {{ "foo", uint64_t(0) }}));
|
||||
ASSERT_TRUE(evaluate(f, {{ "foo", double(0) }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", int64_t(1) }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", uint64_t(1) }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", double(1) }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", std::string("0") }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", false }}));
|
||||
ASSERT_FALSE(evaluate(f, {{ "foo", true }}));
|
||||
ASSERT_FALSE(evaluate(f, {{}}));
|
||||
}
|
||||
|
||||
TEST(FilterComparison, EqualsType) {
|
||||
FilterExpression f = parse("[\"==\", \"$type\", \"LineString\"]");
|
||||
ASSERT_FALSE(evaluate(f, {{}}, FeatureType::Point));
|
||||
ASSERT_TRUE(evaluate(f, {{}}, FeatureType::LineString));
|
||||
}
|
||||
|
||||
TEST(FilterComparison, Any) {
|
||||
ASSERT_FALSE(evaluate(parse("[\"any\"]"), {{}}));
|
||||
ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 1]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
ASSERT_FALSE(evaluate(parse("[\"any\", [\"==\", \"foo\", 0]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
}
|
||||
|
||||
TEST(FilterComparison, All) {
|
||||
ASSERT_TRUE(evaluate(parse("[\"all\"]"), {{}}));
|
||||
ASSERT_TRUE(evaluate(parse("[\"all\", [\"==\", \"foo\", 1]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
ASSERT_FALSE(evaluate(parse("[\"all\", [\"==\", \"foo\", 0]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
ASSERT_FALSE(evaluate(parse("[\"all\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
}
|
||||
|
||||
TEST(FilterComparison, None) {
|
||||
ASSERT_TRUE(evaluate(parse("[\"none\"]"), {{}}));
|
||||
ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 1]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
ASSERT_TRUE(evaluate(parse("[\"none\", [\"==\", \"foo\", 0]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
|
||||
{{ std::string("foo"), int64_t(1) }}));
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/style/function_properties.hpp>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/util/merge_lines.hpp>
|
||||
|
||||
const std::u32string a = U"a";
|
||||
const std::u32string b = U"b";
|
||||
|
||||
TEST(mergeLines, mergeLines) {
|
||||
|
||||
std::u32string a = U"a";
|
||||
std::u32string b = U"b";
|
||||
|
||||
TEST(MergeLines, SameText) {
|
||||
// merges lines with the same text
|
||||
std::vector<mbgl::SymbolFeature> input1 = {
|
||||
{ {{{0, 0}, {1, 0}, {2, 0}}}, a, "" },
|
||||
@@ -18,7 +16,7 @@ TEST(mergeLines, mergeLines) {
|
||||
{ {{{5, 0}, {6, 0}}}, a, "" }
|
||||
};
|
||||
|
||||
std::vector<mbgl::SymbolFeature> expected1 = {
|
||||
const std::vector<mbgl::SymbolFeature> expected1 = {
|
||||
{ {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, a, "" },
|
||||
{ {{{4, 0}, {5, 0}, {6, 0}}}, b, "" },
|
||||
{ {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, a, "" },
|
||||
@@ -32,7 +30,9 @@ TEST(mergeLines, mergeLines) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
EXPECT_EQ(input1[i].geometry, expected1[i].geometry);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MergeLines, BothEnds) {
|
||||
// mergeLines handles merge from both ends
|
||||
std::vector<mbgl::SymbolFeature> input2 = {
|
||||
{ {{{0, 0}, {1, 0}, {2, 0}}}, a, "" },
|
||||
@@ -40,7 +40,7 @@ TEST(mergeLines, mergeLines) {
|
||||
{ {{{2, 0}, {3, 0}, {4, 0}}}, a, "" }
|
||||
};
|
||||
|
||||
std::vector<mbgl::SymbolFeature> expected2 = {
|
||||
const std::vector<mbgl::SymbolFeature> expected2 = {
|
||||
{ {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, a, "" },
|
||||
{ {{}}, a, "" },
|
||||
{ {{}}, a, "" }
|
||||
@@ -51,7 +51,9 @@ TEST(mergeLines, mergeLines) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
EXPECT_EQ(input2[i].geometry, expected2[i].geometry);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(MergeLines, CircularLines) {
|
||||
// mergeLines handles circular lines
|
||||
std::vector<mbgl::SymbolFeature> input3 = {
|
||||
{ {{{0, 0}, {1, 0}, {2, 0}}}, a, "" },
|
||||
@@ -59,7 +61,7 @@ TEST(mergeLines, mergeLines) {
|
||||
{ {{{4, 0}, {0, 0}}}, a, "" }
|
||||
};
|
||||
|
||||
std::vector<mbgl::SymbolFeature> expected3 = {
|
||||
const std::vector<mbgl::SymbolFeature> expected3 = {
|
||||
{ {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, a, "" },
|
||||
{ {{}}, a, "" },
|
||||
{ {{}}, a, "" }
|
||||
26
test/miscellaneous/miscellaneous.gypi
Normal file
26
test/miscellaneous/miscellaneous.gypi
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'test_miscellaneous',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'test_base',
|
||||
'../mapboxgl.gyp:mbgl-core',
|
||||
'../mapboxgl.gyp:mbgl-<(platform)',
|
||||
'../mapboxgl.gyp:mbgl-headless',
|
||||
'../deps/gtest/gtest.gyp:gtest'
|
||||
],
|
||||
'sources': [
|
||||
'main.cpp',
|
||||
'clip_ids.cpp',
|
||||
'comparisons.cpp',
|
||||
'enums.cpp',
|
||||
'functions.cpp',
|
||||
'rotation_range.cpp',
|
||||
'style_parser.cpp',
|
||||
'text_conversions.cpp',
|
||||
'tile.cpp',
|
||||
'variant.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include "./fixtures/fixture_log.hpp"
|
||||
#include "../fixtures/fixture_log.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
const std::string base_directory = []{
|
||||
std::string fn = __FILE__;
|
||||
fn.erase(fn.find_last_of("/"));
|
||||
return fn + "/fixtures/style_parser";
|
||||
}();
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
typedef std::pair<uint32_t, std::string> Message;
|
||||
@@ -26,7 +20,7 @@ typedef std::vector<Message> Messages;
|
||||
class StyleParserTest : public ::testing::TestWithParam<std::string> {};
|
||||
|
||||
TEST_P(StyleParserTest, ParseStyle) {
|
||||
const std::string &base = base_directory + "/" + GetParam();
|
||||
const std::string &base = "test/fixtures/style_parser/" + GetParam();
|
||||
|
||||
const std::string style_path = base + ".style.json";
|
||||
const std::string info = util::read_file(base + ".info.json");
|
||||
@@ -83,19 +77,18 @@ INSTANTIATE_TEST_CASE_P(StyleParser, StyleParserTest, ::testing::ValuesIn([] {
|
||||
std::vector<std::string> names;
|
||||
const std::string ending = ".info.json";
|
||||
|
||||
DIR *dir = opendir(base_directory.c_str());
|
||||
if (dir == nullptr) {
|
||||
return names;
|
||||
}
|
||||
|
||||
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
|
||||
const std::string name = dp->d_name;
|
||||
if (name.length() >= ending.length() && name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
|
||||
names.push_back(name.substr(0, name.length() - ending.length()));
|
||||
const std::string style_directory = "test/fixtures/style_parser";
|
||||
DIR *dir = opendir(style_directory.c_str());
|
||||
if (dir != nullptr) {
|
||||
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
|
||||
const std::string name = dp->d_name;
|
||||
if (name.length() >= ending.length() && name.compare(name.length() - ending.length(), ending.length(), ending) == 0) {
|
||||
names.push_back(name.substr(0, name.length() - ending.length()));
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
EXPECT_GT(names.size(), 0ul);
|
||||
return names;
|
||||
}()));
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/util/utf.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/map/tile.hpp>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "gtest/gtest.h"
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <mbgl/style/value.hpp>
|
||||
#include <mbgl/style/value_comparison.hpp>
|
||||
39
test/storage/cache_response.cpp
Normal file
39
test/storage/cache_response.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
#include <mbgl/storage/default/sqlite_cache.hpp>
|
||||
|
||||
TEST(Storage, CacheResponse) {
|
||||
SCOPED_TEST(CacheResponse);
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
SQLiteCache cache(":memory:");
|
||||
DefaultFileSource fs(&cache, uv_default_loop());
|
||||
|
||||
const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/cache" };
|
||||
|
||||
fs.request(resource, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Response 1");
|
||||
EXPECT_GT(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
fs.request(resource, uv_default_loop(), [&, res](const Response &res2) {
|
||||
EXPECT_EQ(res2.status, res.status);
|
||||
EXPECT_EQ(res2.data, res.data);
|
||||
EXPECT_EQ(res2.expires, res.expires);
|
||||
EXPECT_EQ(res2.modified, res.modified);
|
||||
EXPECT_EQ(res2.etag, res.etag);
|
||||
EXPECT_EQ(res2.message, res.message);
|
||||
|
||||
CacheResponse.finish();
|
||||
});
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
85
test/storage/cache_revalidate.cpp
Normal file
85
test/storage/cache_revalidate.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
#include <mbgl/storage/default/sqlite_cache.hpp>
|
||||
|
||||
TEST(Storage, CacheRevalidate) {
|
||||
SCOPED_TEST(CacheRevalidateSame)
|
||||
SCOPED_TEST(CacheRevalidateModified)
|
||||
SCOPED_TEST(CacheRevalidateEtag)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
SQLiteCache cache(":memory:");
|
||||
DefaultFileSource fs(&cache);
|
||||
|
||||
const Resource revalidateSame { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" };
|
||||
fs.request(revalidateSame, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Response");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "snowfall");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
fs.request(revalidateSame, uv_default_loop(), [&, res](const Response &res2) {
|
||||
EXPECT_EQ(res2.status, Response::Successful);
|
||||
EXPECT_EQ(res2.data, "Response");
|
||||
// We use this to indicate that a 304 reply came back.
|
||||
EXPECT_GT(res2.expires, 0);
|
||||
EXPECT_EQ(res2.modified, 0);
|
||||
// We're not sending the ETag in the 304 reply, but it should still be there.
|
||||
EXPECT_EQ(res2.etag, "snowfall");
|
||||
EXPECT_EQ(res2.message, "");
|
||||
|
||||
CacheRevalidateSame.finish();
|
||||
});
|
||||
});
|
||||
|
||||
const Resource revalidateModified { Resource::Unknown, "http://127.0.0.1:3000/revalidate-modified" };
|
||||
fs.request(revalidateModified, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Response");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 1420070400);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
fs.request(revalidateModified, uv_default_loop(), [&, res](const Response &res2) {
|
||||
EXPECT_EQ(res2.status, Response::Successful);
|
||||
EXPECT_EQ(res2.data, "Response");
|
||||
// We use this to indicate that a 304 reply came back.
|
||||
EXPECT_GT(res2.expires, 0);
|
||||
EXPECT_EQ(res2.modified, 1420070400);
|
||||
EXPECT_EQ(res2.etag, "");
|
||||
EXPECT_EQ(res2.message, "");
|
||||
|
||||
CacheRevalidateModified.finish();
|
||||
});
|
||||
});
|
||||
|
||||
const Resource revalidateEtag { Resource::Unknown, "http://127.0.0.1:3000/revalidate-etag" };
|
||||
fs.request(revalidateEtag, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Response 1");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "response-1");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
fs.request(revalidateEtag, uv_default_loop(), [&, res](const Response &res2) {
|
||||
EXPECT_EQ(res2.status, Response::Successful);
|
||||
EXPECT_EQ(res2.data, "Response 2");
|
||||
EXPECT_EQ(res2.expires, 0);
|
||||
EXPECT_EQ(res2.modified, 0);
|
||||
EXPECT_EQ(res2.etag, "response-2");
|
||||
EXPECT_EQ(res2.message, "");
|
||||
|
||||
CacheRevalidateEtag.finish();
|
||||
});
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
25
test/storage/directory_reading.cpp
Normal file
25
test/storage/directory_reading.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
TEST(Storage, ReadDirectory) {
|
||||
SCOPED_TEST(ReadDirectory)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
fs.request({ Resource::Unknown, "asset://test/fixtures/storage" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Error);
|
||||
EXPECT_EQ(res.data.size(), 0ul);
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "illegal operation on a directory");
|
||||
ReadDirectory.finish();
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
45
test/storage/file_reading.cpp
Normal file
45
test/storage/file_reading.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
TEST(Storage, EmptyFile) {
|
||||
SCOPED_TEST(EmptyFile)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
fs.request({ Resource::Unknown, "asset://test/fixtures/storage/empty" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data.size(), 0ul);
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_GT(res.modified, 0);
|
||||
EXPECT_NE(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
EmptyFile.finish();
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
TEST(Storage, NonExistentFile) {
|
||||
SCOPED_TEST(NonExistentFile)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
fs.request({ Resource::Unknown, "asset://test/fixtures/storage/does_not_exist" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Error);
|
||||
EXPECT_EQ(res.data.size(), 0ul);
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "no such file or directory");
|
||||
NonExistentFile.finish();
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
50
test/storage/http_cancel.cpp
Normal file
50
test/storage/http_cancel.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
TEST(Storage, HTTPCancel) {
|
||||
SCOPED_TEST(HTTPCancel)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &) {
|
||||
ADD_FAILURE() << "Callback should not be called";
|
||||
});
|
||||
|
||||
fs.cancel(req);
|
||||
HTTPCancel.finish();
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
TEST(Storage, HTTPCancelMultiple) {
|
||||
SCOPED_TEST(HTTPCancelMultiple)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" };
|
||||
auto req2 = fs.request(resource, uv_default_loop(), [&](const Response &) {
|
||||
ADD_FAILURE() << "Callback should not be called";
|
||||
});
|
||||
fs.request(resource, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
HTTPCancelMultiple.finish();
|
||||
});
|
||||
fs.cancel(req2);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
48
test/storage/http_coalescing.cpp
Normal file
48
test/storage/http_coalescing.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
TEST(Storage, HTTPCoalescing) {
|
||||
SCOPED_TEST(HTTPCoalescing)
|
||||
|
||||
static int counter = 0;
|
||||
const static int total = 4;
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
static const Response *reference = nullptr;
|
||||
|
||||
const auto complete = [&](const Response &res) {
|
||||
counter++;
|
||||
|
||||
// Make sure all of the Response objects are the same.
|
||||
if (!reference) {
|
||||
reference = &res;
|
||||
} else {
|
||||
EXPECT_EQ(reference, &res);
|
||||
}
|
||||
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
if (counter >= total) {
|
||||
HTTPCoalescing.finish();
|
||||
}
|
||||
};
|
||||
|
||||
const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" };
|
||||
|
||||
for (int i = 0; i < total; i++) {
|
||||
fs.request(resource, uv_default_loop(), complete);
|
||||
}
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
63
test/storage/http_error.cpp
Normal file
63
test/storage/http_error.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
TEST(Storage, HTTPError) {
|
||||
SCOPED_TEST(HTTPTemporaryError)
|
||||
SCOPED_TEST(HTTPConnectionError)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
uv_timer_t statusChange;
|
||||
uv_timer_init(uv_default_loop(), &statusChange);
|
||||
uv_timer_start(&statusChange, [](uv_timer_t *, int) {
|
||||
NetworkStatus::Reachable();
|
||||
}, 500, 500);
|
||||
uv_unref((uv_handle_t *)&statusChange);
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
auto start = uv_hrtime();
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, uv_default_loop(), [&](const Response &res) {
|
||||
const auto duration = double(uv_hrtime() - start) / 1e9;
|
||||
EXPECT_GT(duration, 1) << "Backoff timer didn't wait 1 second";
|
||||
EXPECT_LT(duration, 1.2) << "Backoff timer fired too late";
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
HTTPTemporaryError.finish();
|
||||
});
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3001/" }, uv_default_loop(), [&](const Response &res) {
|
||||
const auto duration = double(uv_hrtime() - start) / 1e9;
|
||||
// 1.5 seconds == 4 retries, with a 500ms timeout (see above).
|
||||
EXPECT_GT(duration, 1.5) << "Resource wasn't retried the correct number of times";
|
||||
EXPECT_LT(duration, 1.7) << "Resource wasn't retried the correct number of times";
|
||||
EXPECT_EQ(res.status, Response::Error);
|
||||
EXPECT_TRUE(res.message == "Couldn't connect to server" || res.message == "The operation couldn’t be completed. (NSURLErrorDomain error -1004.)");
|
||||
EXPECT_EQ(res.data, "");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
HTTPConnectionError.finish();
|
||||
});
|
||||
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
uv_timer_stop(&statusChange);
|
||||
uv_close(reinterpret_cast<uv_handle_t *>(&statusChange), nullptr);
|
||||
|
||||
// Run again so that the timer handle can be properly closed.
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
42
test/storage/http_header_parsing.cpp
Normal file
42
test/storage/http_header_parsing.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
TEST(Storage, HTTPHeaderParsing) {
|
||||
SCOPED_TEST(HTTPExpiresTest)
|
||||
SCOPED_TEST(HTTPCacheControlTest)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?modified=1420794326&expires=1420797926&etag=foo" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 1420797926);
|
||||
EXPECT_EQ(res.modified, 1420794326);
|
||||
EXPECT_EQ(res.etag, "foo");
|
||||
EXPECT_EQ(res.message, "");
|
||||
HTTPExpiresTest.finish();
|
||||
});
|
||||
|
||||
|
||||
int64_t now = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?cachecontrol=max-age=120" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_LT(std::abs(res.expires - now - 120), 2) << "Expiration date isn't about 120 seconds in the future";
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
HTTPCacheControlTest.finish();
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
44
test/storage/http_load.cpp
Normal file
44
test/storage/http_load.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
|
||||
|
||||
TEST(Storage, HTTPLoad) {
|
||||
SCOPED_TEST(HTTPLoad)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
const int concurrency = 50;
|
||||
const int max = 10000;
|
||||
int number = 1;
|
||||
|
||||
std::function<void()> req = [&]() {
|
||||
const auto current = number++;
|
||||
fs.request({ Resource::Unknown, std::string("http://127.0.0.1:3000/load/") + std::to_string(current) }, uv_default_loop(), [&, current](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, std::string("Request ") + std::to_string(current));
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
|
||||
if (number <= max) {
|
||||
req();
|
||||
} else if (current == max) {
|
||||
HTTPLoad.finish();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
for (int i = 0; i < concurrency; i++) {
|
||||
req();
|
||||
}
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
37
test/storage/http_noloop.cpp
Normal file
37
test/storage/http_noloop.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
|
||||
TEST(Storage, HTTPNoLoop) {
|
||||
SCOPED_TEST(HTTPNoLoop)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr);
|
||||
|
||||
const auto mainThread = uv_thread_self();
|
||||
|
||||
// Async handle that keeps the main loop alive until the thread finished
|
||||
auto async = new uv_async_t;
|
||||
uv_async_init(uv_default_loop(), async, [] (uv_async_t *as, int) {
|
||||
uv::close(as);
|
||||
});
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, [&](const Response &res) {
|
||||
EXPECT_NE(mainThread, uv_thread_self()) << "Response was called in the same thread";
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
HTTPNoLoop.finish();
|
||||
|
||||
uv_async_send(async);
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
26
test/storage/http_other_loop.cpp
Normal file
26
test/storage/http_other_loop.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
TEST(Storage, HTTPOtherLoop) {
|
||||
SCOPED_TEST(HTTPOtherLoop)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
// This file source launches a separate thread to do the processing.
|
||||
DefaultFileSource fs(nullptr);
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
HTTPOtherLoop.finish();
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
39
test/storage/http_reading.cpp
Normal file
39
test/storage/http_reading.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "../util.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/storage/default/default_file_source.hpp>
|
||||
|
||||
TEST(Storage, HTTPReading) {
|
||||
SCOPED_TEST(HTTPTest)
|
||||
SCOPED_TEST(HTTP404)
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
DefaultFileSource fs(nullptr, uv_default_loop());
|
||||
|
||||
const auto mainThread = uv_thread_self();
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(mainThread, uv_thread_self());
|
||||
EXPECT_EQ(res.status, Response::Successful);
|
||||
EXPECT_EQ(res.data, "Hello World!");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
EXPECT_EQ(res.message, "");
|
||||
HTTPTest.finish();
|
||||
});
|
||||
|
||||
fs.request({ Resource::Unknown, "http://127.0.0.1:3000/doesnotexist" }, uv_default_loop(), [&](const Response &res) {
|
||||
EXPECT_EQ(mainThread, uv_thread_self());
|
||||
EXPECT_EQ(res.status, Response::Error);
|
||||
EXPECT_EQ(res.message, "HTTP status code 404");
|
||||
EXPECT_EQ(res.expires, 0);
|
||||
EXPECT_EQ(res.modified, 0);
|
||||
EXPECT_EQ(res.etag, "");
|
||||
HTTP404.finish();
|
||||
});
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
}
|
||||
101
test/storage/server.js
Executable file
101
test/storage/server.js
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env node
|
||||
/* jshint node: true */
|
||||
'use strict';
|
||||
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
|
||||
// We're manually setting Etag headers.
|
||||
app.disable('etag');
|
||||
|
||||
app.get('/test', function (req, res) {
|
||||
if (req.query.modified) {
|
||||
res.setHeader('Last-Modified', (new Date(req.query.modified * 1000)).toUTCString());
|
||||
}
|
||||
if (req.query.expires) {
|
||||
res.setHeader('Expires', (new Date(req.query.expires * 1000)).toUTCString());
|
||||
}
|
||||
if (req.query.etag) {
|
||||
res.setHeader('ETag', req.query.etag);
|
||||
}
|
||||
if (req.query.cachecontrol) {
|
||||
res.setHeader('Cache-Control', req.query.cachecontrol);
|
||||
}
|
||||
res.send('Hello World!');
|
||||
});
|
||||
|
||||
|
||||
var cacheCounter = 0;
|
||||
app.get('/cache', function(req, res) {
|
||||
res.setHeader('Cache-Control', 'max-age=30'); // Allow caching for 30 seconds
|
||||
res.send('Response ' + (++cacheCounter));
|
||||
});
|
||||
|
||||
app.get('/revalidate-same', function(req, res) {
|
||||
if (req.headers['if-none-match'] == 'snowfall') {
|
||||
// Second request can be cached for 30 seconds.
|
||||
res.setHeader('Cache-Control', 'max-age=30');
|
||||
res.status(304).end();
|
||||
} else {
|
||||
// First request must always be revalidated.
|
||||
res.setHeader('ETag', 'snowfall');
|
||||
res.setHeader('Cache-Control', 'must-revalidate');
|
||||
res.status(200).send('Response');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.get('/revalidate-modified', function(req, res) {
|
||||
var jan1 = new Date('jan 1 2015 utc');
|
||||
|
||||
if (req.headers['if-modified-since']) {
|
||||
var modified_since = new Date(req.headers['if-modified-since']);
|
||||
if (modified_since >= jan1) {
|
||||
res.setHeader('Cache-Control', 'max-age=30');
|
||||
res.status(304).end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// First request must always be revalidated.
|
||||
res.setHeader('Last-Modified', jan1.toUTCString());
|
||||
res.setHeader('Cache-Control', 'must-revalidate');
|
||||
res.status(200).send('Response');
|
||||
});
|
||||
|
||||
|
||||
var revalidateEtagCounter = 1;
|
||||
app.get('/revalidate-etag', function(req, res) {
|
||||
res.setHeader('ETag', 'response-' + revalidateEtagCounter);
|
||||
res.setHeader('Cache-Control', 'must-revalidate');
|
||||
|
||||
res.status(200).send('Response ' + revalidateEtagCounter);
|
||||
revalidateEtagCounter++;
|
||||
});
|
||||
|
||||
|
||||
var temporaryErrorCounter = 0;
|
||||
app.get('/temporary-error', function(req, res) {
|
||||
if (temporaryErrorCounter === 0) {
|
||||
res.status(500).end();
|
||||
} else {
|
||||
res.status(200).send('Hello World!');
|
||||
}
|
||||
|
||||
temporaryErrorCounter++;
|
||||
});
|
||||
|
||||
app.get('/load/:number(\\d+)', function(req, res) {
|
||||
res.send('Request ' + req.params.number);
|
||||
});
|
||||
|
||||
var server = app.listen(3000, function () {
|
||||
var host = server.address().address;
|
||||
var port = server.address().port;
|
||||
console.log('Test server listening at http://%s:%s', host, port);
|
||||
|
||||
if (process.argv[2]) {
|
||||
// Allow the test to continue running.
|
||||
process.kill(+process.argv[2], 'SIGCONT');
|
||||
}
|
||||
});
|
||||
28
test/storage/storage.gypi
Normal file
28
test/storage/storage.gypi
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'test_storage',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'test_base',
|
||||
'../mapboxgl.gyp:mbgl-core',
|
||||
'../mapboxgl.gyp:mbgl-<(platform)',
|
||||
'../deps/gtest/gtest.gyp:gtest'
|
||||
],
|
||||
'sources': [
|
||||
'main.cpp',
|
||||
'cache_response.cpp',
|
||||
'cache_revalidate.cpp',
|
||||
'directory_reading.cpp',
|
||||
'file_reading.cpp',
|
||||
'http_cancel.cpp',
|
||||
'http_coalescing.cpp',
|
||||
'http_error.cpp',
|
||||
'http_header_parsing.cpp',
|
||||
'http_load.cpp',
|
||||
'http_noloop.cpp',
|
||||
'http_other_loop.cpp',
|
||||
'http_reading.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
314
test/test.gyp
314
test/test.gyp
@@ -4,265 +4,73 @@
|
||||
'../gyp/version.gypi',
|
||||
'../gyp/mbgl-platform.gypi',
|
||||
],
|
||||
'variables' : {
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(uv_static_libs)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
'<@(png_ldflags)',
|
||||
],
|
||||
},
|
||||
'targets': [
|
||||
{ 'target_name': 'rotation_range',
|
||||
'product_name': 'test_rotation_range',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./rotation_range.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'clip_ids',
|
||||
'product_name': 'test_clip_ids',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./clip_ids.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)'] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'enums',
|
||||
'product_name': 'test_enums',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./enums.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)'] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'style_parser',
|
||||
'product_name': 'test_style_parser',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./style_parser.cpp',
|
||||
'./fixtures/fixture_log.hpp',
|
||||
'./fixtures/fixture_log.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone'
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'variant',
|
||||
'product_name': 'test_variant',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./variant.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'comparisons',
|
||||
'product_name': 'test_comparisons',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./comparisons.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'tile',
|
||||
'product_name': 'test_tile',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./tile.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'functions',
|
||||
'product_name': 'test_functions',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./functions.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'merge_lines',
|
||||
'product_name': 'test_merge_lines',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./merge_lines.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'conditions': [
|
||||
['OS == "mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'headless',
|
||||
'product_name': 'test_headless',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./headless.cpp',
|
||||
'./fixtures/fixture_log.cpp',
|
||||
],
|
||||
'conditions': [
|
||||
# add libuv include path and OpenGL libs
|
||||
['OS == "mac"',
|
||||
{
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': ['<@(uv_cflags)','<@(png_cflags)'],
|
||||
'OTHER_LDFLAGS': ['<@(glfw3_ldflags)', '<@(ldflags)'],
|
||||
},
|
||||
},
|
||||
{
|
||||
'cflags': ['<@(uv_cflags)','<@(png_cflags)'],
|
||||
'libraries': ['<@(glfw3_ldflags)', '<@(ldflags)'],
|
||||
}],
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-core',
|
||||
'../mapboxgl.gyp:mbgl-headless',
|
||||
'<(platform_library)',
|
||||
],
|
||||
'include_dirs': [ '../src' ]
|
||||
},
|
||||
{ 'target_name': 'text_conversions',
|
||||
'product_name': 'test_text_conversions',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'./text_conversions.cpp',
|
||||
],
|
||||
'dependencies': [
|
||||
'../deps/gtest/gtest.gyp:gtest',
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
'<(platform_library)',
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'-I<(boost_root)/include',
|
||||
]
|
||||
{ 'target_name': 'test_base',
|
||||
'type': 'none',
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [ '../include', '../src' ],
|
||||
},
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
'<@(glfw3_static_libs)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(zlib_static_libs)',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [
|
||||
'<@(uv_ldflags)',
|
||||
'<@(glfw3_ldflags)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(zlib_ldflags)',
|
||||
],
|
||||
'OTHER_CFLAGS': [ '<@(uv_cflags)' ],
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(uv_cflags)' ],
|
||||
},
|
||||
'cflags': [ '<@(uv_cflags)' ],
|
||||
'cxxflags': [ '<@(uv_cflags)' ],
|
||||
},
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)', '-framework Foundation' ]
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'libraries': [ '<@(ldflags)'],
|
||||
}]
|
||||
]
|
||||
},
|
||||
|
||||
# Build all targets
|
||||
{ 'target_name': 'test',
|
||||
'type': 'none',
|
||||
'type': 'executable',
|
||||
'dependencies': [
|
||||
'rotation_range',
|
||||
'clip_ids',
|
||||
'enums',
|
||||
'variant',
|
||||
'tile',
|
||||
'functions',
|
||||
'merge_lines',
|
||||
'headless',
|
||||
'style_parser',
|
||||
'comparisons',
|
||||
'text_conversions',
|
||||
'test_base',
|
||||
'../mapboxgl.gyp:mbgl-core',
|
||||
'../mapboxgl.gyp:mbgl-<(platform)',
|
||||
'../mapboxgl.gyp:mbgl-headless',
|
||||
'../deps/gtest/gtest.gyp:gtest'
|
||||
],
|
||||
}
|
||||
'sources': [
|
||||
'main.cpp',
|
||||
|
||||
'headless/headless.cpp',
|
||||
|
||||
'miscellaneous/clip_ids.cpp',
|
||||
'miscellaneous/comparisons.cpp',
|
||||
'miscellaneous/enums.cpp',
|
||||
'miscellaneous/functions.cpp',
|
||||
'miscellaneous/merge_lines.cpp',
|
||||
'miscellaneous/rotation_range.cpp',
|
||||
'miscellaneous/style_parser.cpp',
|
||||
'miscellaneous/text_conversions.cpp',
|
||||
'miscellaneous/tile.cpp',
|
||||
'miscellaneous/variant.cpp',
|
||||
|
||||
'storage/cache_response.cpp',
|
||||
'storage/cache_revalidate.cpp',
|
||||
'storage/directory_reading.cpp',
|
||||
'storage/file_reading.cpp',
|
||||
'storage/http_cancel.cpp',
|
||||
'storage/http_coalescing.cpp',
|
||||
'storage/http_error.cpp',
|
||||
'storage/http_header_parsing.cpp',
|
||||
'storage/http_load.cpp',
|
||||
'storage/http_noloop.cpp',
|
||||
'storage/http_other_loop.cpp',
|
||||
'storage/http_reading.cpp',
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
14
test/util.hpp
Normal file
14
test/util.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef MBGL_TEST_UTIL
|
||||
#define MBGL_TEST_UTIL
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define SCOPED_TEST(name) \
|
||||
static class name { \
|
||||
bool completed = false; \
|
||||
public: \
|
||||
void finish() { EXPECT_FALSE(completed) << #name " was already completed."; completed = true; } \
|
||||
~name() { if (!completed) ADD_FAILURE() << #name " didn't complete."; } \
|
||||
} name;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user