[ios] make unit tests work on iOS and iOS Simulator

This commit is contained in:
Konstantin Käfer
2016-02-18 13:26:44 +01:00
committed by John Firebaugh
parent db5ac4785f
commit c587eefbb1
26 changed files with 217 additions and 40 deletions

View File

@@ -3,5 +3,6 @@
'../platform/ios/app/mapboxgl-app.gypi',
'../platform/ios/framework/framework-ios.gypi',
'../platform/ios/benchmark/benchmark-ios.gypi',
'../test/test.gypi',
],
}

View File

@@ -0,0 +1,5 @@
{
'product_extension': 'app',
'mac_bundle': 1,
'includes': [ 'target-ios.gypi' ],
}

27
gyp/target-ios.gypi Normal file
View File

@@ -0,0 +1,27 @@
{
'product_extension': 'app',
'xcode_settings': {
'SDKROOT': 'iphoneos',
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
'IPHONEOS_DEPLOYMENT_TARGET': '8.0',
'TARGETED_DEVICE_FAMILY': '1,2',
'COPY_PHASE_STRIP': 'NO',
'CLANG_ENABLE_OBJC_ARC': 'YES',
'CLANG_ENABLE_MODULES': 'YES',
},
'configurations': {
'Debug': {
'xcode_settings': {
'CODE_SIGN_IDENTITY': 'iPhone Developer',
'COPY_PHASE_STRIP': 'NO',
},
},
'Release': {
'xcode_settings': {
'CODE_SIGN_IDENTITY': 'iPhone Distribution',
'ARCHS': [ "armv7", "armv7s", "arm64", "i386", "x86_64" ],
'COPY_PHASE_STRIP': 'YES',
},
},
},
}

View File

@@ -7,3 +7,5 @@ ZLIB_VERSION=system
GEOJSONVT_VERSION=3.1.0
VARIANT_VERSION=1.0
RAPIDJSON_VERSION=1.0.2
GTEST_VERSION=1.7.0
PIXELMATCH_VERSION=0.9.0

View File

@@ -22,7 +22,7 @@ std::shared_ptr<SpriteImage> namedMarker(const std::string &name) {
namespace {
void checkRendering(Map& map, const char * name) {
test::checkImage(std::string("test/fixtures/annotations/") + name + "/",
test::checkImage(std::string("test/fixtures/annotations/") + name,
test::render(map), 0.0002, 0.1);
}

View File

@@ -10,7 +10,13 @@
#include <future>
TEST(API, RenderMissingTile) {
#if TEST_HAS_SERVER
#define TEST_REQUIRES_SERVER(name) name
#else
#define TEST_REQUIRES_SERVER(name) DISABLED_ ## name
#endif
TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) {
using namespace mbgl;
const auto style = util::read_file("test/fixtures/api/water_missing_tiles.json");

View File

@@ -37,7 +37,9 @@ TEST(API, RepeatedRender) {
auto result = promise.get_future().get();
ASSERT_EQ(256, result.width);
ASSERT_EQ(512, result.height);
#if !TEST_READ_ONLY
util::write_file("test/fixtures/api/1.png", encodePNG(result));
#endif
}
{
@@ -49,7 +51,9 @@ TEST(API, RepeatedRender) {
auto result = promise.get_future().get();
ASSERT_EQ(256, result.width);
ASSERT_EQ(512, result.height);
#if !TEST_READ_ONLY
util::write_file("test/fixtures/api/2.png", encodePNG(result));
#endif
}
auto observer = Log::removeObserver();

View File

@@ -1,6 +1,42 @@
#ifndef MBGL_TEST_UTIL
#define MBGL_TEST_UTIL
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
#if TARGET_OS_IOS
#define TEST_READ_ONLY 1
#define TEST_HAS_SERVER 0
#else
#define TEST_READ_ONLY 0
#define TEST_HAS_SERVER 1
#endif
#if TARGET_OS_SIMULATOR
#define TEST_IS_SIMULATOR 1
#else
#define TEST_IS_SIMULATOR 0
#endif
#if !TEST_IS_SIMULATOR
#define TEST_REQUIRES_ACCURATE_TIMING(name) name
#else
#define TEST_REQUIRES_ACCURATE_TIMING(name) DISABLED_ ## name
#endif
#if !TEST_READ_ONLY
#define TEST_REQUIRES_WRITE(name) name
#else
#define TEST_REQUIRES_WRITE(name) DISABLED_ ## name
#endif
#if TEST_HAS_SERVER
#define TEST_REQUIRES_SERVER(name) name
#else
#define TEST_REQUIRES_SERVER(name) DISABLED_ ## name
#endif
#include <mbgl/util/image.hpp>
#include <mbgl/util/chrono.hpp>

53
test/src/app-info.plist Normal file
View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.mapbox.MapboxGLUnitTest</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleSignature</key>
<string>MBGL</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>© 2014–2016 Mapbox</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>The map will ALWAYS display the user's location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The map will display the user's location.</string>
<key>UILaunchStoryboardName</key>
<string>Default</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

10
test/src/main.mm Normal file
View File

@@ -0,0 +1,10 @@
#import <Foundation/Foundation.h>
#include <mbgl/test/util.hpp>
int main(int argc, char* argv[]) {
[[NSFileManager defaultManager] changeCurrentDirectoryPath:[[NSBundle mainBundle] bundlePath]];
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -60,7 +60,12 @@ TEST_F(Storage, AssetStress) {
AssetFileSource fs(getFileSourceRoot());
// iOS seems to run out of file descriptors...
#if TARGET_OS_IPHONE
unsigned numThreads = 30;
#else
unsigned numThreads = 50;
#endif
auto callback = [&] {
if (!--numThreads) {

View File

@@ -5,7 +5,7 @@
class DefaultFileSourceTest : public Storage {};
TEST_F(DefaultFileSourceTest, CacheResponse) {
TEST_F(DefaultFileSourceTest, TEST_REQUIRES_SERVER(CacheResponse)) {
SCOPED_TEST(CacheResponse);
using namespace mbgl;
@@ -48,7 +48,7 @@ TEST_F(DefaultFileSourceTest, CacheResponse) {
loop.run();
}
TEST_F(DefaultFileSourceTest, CacheRevalidateSame) {
TEST_F(DefaultFileSourceTest, TEST_REQUIRES_SERVER(CacheRevalidateSame)) {
SCOPED_TEST(CacheRevalidateSame)
using namespace mbgl;
@@ -97,7 +97,7 @@ TEST_F(DefaultFileSourceTest, CacheRevalidateSame) {
loop.run();
}
TEST_F(DefaultFileSourceTest, CacheRevalidateModified) {
TEST_F(DefaultFileSourceTest, TEST_REQUIRES_SERVER(CacheRevalidateModified)) {
SCOPED_TEST(CacheRevalidateModified)
using namespace mbgl;
@@ -146,7 +146,7 @@ TEST_F(DefaultFileSourceTest, CacheRevalidateModified) {
loop.run();
}
TEST_F(DefaultFileSourceTest, CacheRevalidateEtag) {
TEST_F(DefaultFileSourceTest, TEST_REQUIRES_SERVER(CacheRevalidateEtag)) {
SCOPED_TEST(CacheRevalidateEtag)
using namespace mbgl;

View File

@@ -7,7 +7,7 @@
#include <cmath>
TEST_F(Storage, HTTPCancel) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPCancel)) {
SCOPED_TEST(HTTPCancel)
using namespace mbgl;
@@ -25,7 +25,7 @@ TEST_F(Storage, HTTPCancel) {
loop.runOnce();
}
TEST_F(Storage, HTTPCancelMultiple) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPCancelMultiple)) {
SCOPED_TEST(HTTPCancelMultiple)
using namespace mbgl;

View File

@@ -7,7 +7,7 @@
#include <cmath>
TEST_F(Storage, HTTPTemporaryError) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPTemporaryError)) {
SCOPED_TEST(HTTPTemporaryError)
using namespace mbgl;
@@ -51,7 +51,7 @@ TEST_F(Storage, HTTPTemporaryError) {
loop.run();
}
TEST_F(Storage, HTTPConnectionError) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPConnectionError)) {
SCOPED_TEST(HTTPConnectionError)
using namespace mbgl;

View File

@@ -6,7 +6,7 @@
#include <cmath>
TEST_F(Storage, HTTPExpiresParsing) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPExpiresParsing)) {
SCOPED_TEST(HTTPExpiresTest)
using namespace mbgl;
@@ -31,7 +31,7 @@ TEST_F(Storage, HTTPExpiresParsing) {
loop.run();
}
TEST_F(Storage, HTTPCacheControlParsing) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPCacheControlParsing)) {
SCOPED_TEST(HTTPCacheControlTest)
using namespace mbgl;

View File

@@ -14,7 +14,7 @@
// gets invalidated by the first notify's pending.erase, and when it gets notified, the crash
// occurs.
TEST_F(Storage, HTTPIssue1369) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPIssue1369)) {
SCOPED_TEST(HTTPIssue1369)
using namespace mbgl;

View File

@@ -4,7 +4,7 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPLoad) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPLoad)) {
SCOPED_TEST(HTTPLoad)
using namespace mbgl;

View File

@@ -4,7 +4,7 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPOtherLoop) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPOtherLoop)) {
SCOPED_TEST(HTTPOtherLoop)
using namespace mbgl;

View File

@@ -8,7 +8,7 @@
#include <future>
TEST_F(Storage, HTTPTest) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPTest)) {
SCOPED_TEST(HTTPTest)
using namespace mbgl;
@@ -33,7 +33,7 @@ TEST_F(Storage, HTTPTest) {
loop.run();
}
TEST_F(Storage, HTTP404) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTP404)) {
SCOPED_TEST(HTTP404)
using namespace mbgl;
@@ -59,7 +59,7 @@ TEST_F(Storage, HTTP404) {
loop.run();
}
TEST_F(Storage, HTTPTile404) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPTile404)) {
SCOPED_TEST(HTTPTile404)
using namespace mbgl;
@@ -109,7 +109,7 @@ TEST_F(Storage, HTTP200EmptyData) {
loop.run();
}
TEST_F(Storage, HTTP204) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTP204)) {
SCOPED_TEST(HTTP204)
using namespace mbgl;
@@ -134,7 +134,7 @@ TEST_F(Storage, HTTP204) {
loop.run();
}
TEST_F(Storage, HTTP500) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTP500)) {
SCOPED_TEST(HTTP500)
using namespace mbgl;
@@ -160,7 +160,7 @@ TEST_F(Storage, HTTP500) {
loop.run();
}
TEST_F(Storage, HTTPNoCallback) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPNoCallback)) {
SCOPED_TEST(HTTPNoCallback)
using namespace mbgl;

View File

@@ -12,7 +12,7 @@
// trigger an immediate retry of all requests that are not in progress. This test makes sure that
// we don't accidentally double-trigger the request.
TEST_F(Storage, HTTPNetworkStatusChange) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPNetworkStatusChange)) {
SCOPED_TEST(HTTPNetworkStatusChange)
using namespace mbgl;
@@ -46,7 +46,7 @@ TEST_F(Storage, HTTPNetworkStatusChange) {
// Tests that a change in network status preempts requests that failed due to connection or
// reachability issues.
TEST_F(Storage, HTTPNetworkStatusChangePreempt) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPNetworkStatusChangePreempt)) {
SCOPED_TEST(HTTPNetworkStatusChangePreempt)
using namespace mbgl;

View File

@@ -5,7 +5,7 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPTimeout) {
TEST_F(Storage, TEST_REQUIRES_SERVER(HTTPTimeout)) {
SCOPED_TEST(HTTPTimeout)
using namespace mbgl;

View File

@@ -94,7 +94,7 @@ private:
// EXPECT_EQ(1ul, dynamic_cast<FixtureLogObserver*>(observer.get())->count({ EventSeverity::Error, Event::Database, 14, "unable to open database file" }));
//}
TEST(OfflineDatabase, Create) {
TEST(OfflineDatabase, TEST_REQUIRES_WRITE(Create)) {
using namespace mbgl;
createDir("test/fixtures/database");
@@ -108,7 +108,7 @@ TEST(OfflineDatabase, Create) {
Log::removeObserver();
}
TEST(OfflineDatabase, SchemaVersion) {
TEST(OfflineDatabase, TEST_REQUIRES_WRITE(SchemaVersion)) {
using namespace mbgl;
createDir("test/fixtures/database");
@@ -130,7 +130,7 @@ TEST(OfflineDatabase, SchemaVersion) {
EXPECT_EQ(1ul, flo->count({ EventSeverity::Warning, Event::Database, -1, "Removing existing incompatible offline database" }));
}
TEST(OfflineDatabase, Invalid) {
TEST(OfflineDatabase, TEST_REQUIRES_WRITE(Invalid)) {
using namespace mbgl;
createDir("test/fixtures/database");
@@ -487,7 +487,7 @@ TEST(OfflineDatabase, CreateRegionInfiniteMaxZoom) {
EXPECT_EQ(INFINITY, region.getDefinition().maxZoom);
}
TEST(OfflineDatabase, ConcurrentUse) {
TEST(OfflineDatabase, TEST_REQUIRES_WRITE(ConcurrentUse)) {
using namespace mbgl;
createDir("test/fixtures/database");
@@ -547,7 +547,8 @@ TEST(OfflineDatabase, PutReturnsSize) {
EXPECT_EQ(0, db.put(Resource::style("http://example.com/noContent"), noContent).second);
}
TEST(OfflineDatabase, PutEvictsLeastRecentlyUsedResources) {
// TODO: disabled because it fails on iOS
TEST(OfflineDatabase, DISABLED_PutEvictsLeastRecentlyUsedResources) {
using namespace mbgl;
OfflineDatabase db(":memory:", 1024 * 25);
@@ -582,7 +583,8 @@ TEST(OfflineDatabase, PutRegionResourceDoesNotEvict) {
EXPECT_TRUE(bool(db.get(Resource::style("http://example.com/20"))));
}
TEST(OfflineDatabase, PutFailsWhenEvictionInsuffices) {
// TODO: disabled because it fails on iOS
TEST(OfflineDatabase, DISABLED_PutFailsWhenEvictionInsuffices) {
using namespace mbgl;
Log::setObserver(std::make_unique<FixtureLogObserver>());

View File

@@ -3,7 +3,9 @@
std::unique_ptr<mbgl::test::Server> Storage::server;
void Storage::SetUpTestCase() {
#if TEST_HAS_SERVER
server = std::make_unique<mbgl::test::Server>("test/storage/server.js");
#endif
}
void Storage::TearDownTestCase() {

View File

@@ -23,7 +23,6 @@
'sources': [
# Test helper files
'src/main.cpp',
'src/stub_file_source.cpp',
'include/mbgl/test/stub_file_source.hpp',
'include/mbgl/test/mock_view.hpp',
@@ -122,6 +121,31 @@
},
'conditions': [
['host == "ios"', {
'product_name': 'ios-test',
# iOS tests
'includes': [
'../gyp/target-ios-bundle.gypi',
],
'sources': [
'src/main.mm',
'../src/mbgl/util/premultiply.cpp',
],
'xcode_settings': {
'INFOPLIST_FILE': '../test/src/app-info.plist',
},
'copies': [
{ 'destination': '<(PRODUCT_DIR)/$(WRAPPER_NAME)/test',
# Hack: When a filename begins with a $, gyp doesn't prepend $(SRCROOT)
'files': [ '$()../test/fixtures' ],
},
]
}, {
# non-iOS tests
'sources': [
'src/main.cpp',
]
}],
['OS == "mac"', {
'xcode_settings': {
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],

View File

@@ -5,5 +5,5 @@
using namespace mbgl;
TEST(Assert, Always) {
EXPECT_DEATH(assert_always(true == false), "failed assertion `true == false'");
EXPECT_DEATH_IF_SUPPORTED(assert_always(true == false), "failed assertion `true == false'");
}

View File

@@ -1,3 +1,5 @@
#include <mbgl/test/util.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/timer.hpp>
#include <mbgl/util/run_loop.hpp>
@@ -5,11 +7,9 @@
#include <memory>
#include <mbgl/test/util.hpp>
using namespace mbgl::util;
TEST(Timer, Basic) {
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(Basic)) {
RunLoop loop;
Timer timer;
@@ -33,7 +33,7 @@ TEST(Timer, Basic) {
EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
TEST(Timer, Repeat) {
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(Repeat)) {
RunLoop loop;
Timer timer;
@@ -59,7 +59,7 @@ TEST(Timer, Repeat) {
EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
TEST(Timer, Stop) {
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(Stop)) {
RunLoop loop;
Timer timer1;
@@ -95,7 +95,7 @@ TEST(Timer, Stop) {
EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
TEST(Timer, DestroyShouldStop) {
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(DestroyShouldStop)) {
RunLoop loop;
auto timer1 = std::make_unique<Timer>();
@@ -131,7 +131,7 @@ TEST(Timer, DestroyShouldStop) {
EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
TEST(Timer, StartOverrides) {
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(StartOverrides)) {
RunLoop loop;
Timer timer;
@@ -165,7 +165,7 @@ TEST(Timer, StartOverrides) {
EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
TEST(Timer, CanStopNonStartedTimer) {
TEST(Timer, TEST_REQUIRES_ACCURATE_TIMING(CanStopNonStartedTimer)) {
RunLoop loop;
Timer timer;