diff --git a/.gitignore b/.gitignore index 32edd1bef..08716f371 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .DS_Store *.xcodeproj *.o +*.actual.png +/node_modules /mapnik-packaging /macosx/build /ios/build @@ -14,3 +16,4 @@ /src/shader/shaders_gles2.cpp /bin/style.bin.js access_token.hpp +/test/fixtures/styles/index.html diff --git a/.travis.yml b/.travis.yml index f2349fdd3..dddd096c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,13 @@ env: matrix: - BUILDTYPE=Release - BUILDTYPE=Debug + global: + - secure: "bG4YYWMfl9API0MSRgmOaJrlGLv06tRg9KJNawBieZvBJbITPpxVGJZT3/l/SEJ+Rl15e2dRex4k+MGQlmT2SqPQxTEYWv1qxNigKPPcla7IWeNmWWqW8uVvFjdglojgBOK2k/xErVQtA4zDfi3mwSXH4DKwquXWsoEKmX2SV7M=" + - secure: "Cbvap9ubVKgjPe3hUhI6JGeDZzBXHpOG9RaYKh+SdoIPhKnlJiNOYm1egomi+e4uqJInlFKuVHTw7Ng9Cun6Zm0jIxpkSchv1GpsR7hmB3UGnGed19Dw8121FwuUaktN+4YnbVlsyd+u8EHD3+h58t4eELrLrZolM4rS7DL6caA=" before_install: -- source ./scripts/setup_travis.sh +- ./scripts/setup_travis.sh +- source ./scripts/flags.sh install: - make setup @@ -22,8 +26,12 @@ before_script: - rm -rf mapnik-packaging/out/packages script: -- make linux BUILDTYPE=${BUILDTYPE} -- make run-tests BUILDTYPE=${BUILDTYPE} +- make linux -j4 BUILDTYPE=${BUILDTYPE} +- make test -j4 BUILDTYPE=${BUILDTYPE} +- ./scripts/run_tests.sh + +after_script: +- ./scripts/deploy_results.sh notifications: hipchat: diff --git a/Makefile b/Makefile index b10b7880a..13af0f4ba 100644 --- a/Makefile +++ b/Makefile @@ -27,10 +27,6 @@ build/test/Makefile: src common config.gypi test/test.gyp test: build/test/Makefile $(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) test -# Runs all test cases -run-tests: test - (cd build/${BUILDTYPE} && exec find . -maxdepth 1 -name "test_*" -exec {} \;) - test/%: build/test/Makefile $(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) $* (cd build/$(BUILDTYPE) && exec ./test_$*) @@ -82,9 +78,9 @@ xproj: config.gypi macosx/llmr-app.gyp clear_xcode_cache node open ./build/macosx/llmr-app.xcodeproj # build iOS project for Xcode -iproj: config.gypi ios/llmr-app.gyp clear_xcode_cache node - deps/run_gyp ios/llmr-app.gyp --depth=. --generator-output=./build -f xcode - open ./build/ios/llmr-app.xcodeproj +iproj: config.gypi ios/mapbox-gl-cocoa/app/llmr-app.gyp clear_xcode_cache node + deps/run_gyp ios/mapbox-gl-cocoa/app/llmr-app.gyp --depth=. --generator-output=./build -f xcode + open ./build/ios/mapbox-gl-cocoa/app/llmr-app.xcodeproj # build Linux project for Xcode (Runs on Mac OS X too, but without platform-specific code) lproj: config.gypi linux/llmr-app.gyp clear_xcode_cache node diff --git a/bin/build-shaders.js b/bin/build-shaders.js index b5072c370..9679521e6 100755 --- a/bin/build-shaders.js +++ b/bin/build-shaders.js @@ -117,12 +117,14 @@ module.exports = function(shader_type, prefix, suffix) { code += '\n};\n'; code += suffix + '\n'; - var file_path = path.join(process.argv[2], 'include/llmr/shader/shaders.hpp'); - mkdirp.sync(path.dirname(file_path)); - fs.writeFileSync(file_path, header); - var header_path = path.join(process.argv[2], 'src/shader/shaders_' + shader_type + '.cpp'); + var header_path = path.join(process.argv[2], 'include/llmr/shader/shaders.hpp'); mkdirp.sync(path.dirname(header_path)); - fs.writeFileSync(header_path, code); + fs.writeFileSync(header_path, header); + console.warn('wrote file ' + header_path); + var file_path = path.join(process.argv[2], 'src/shader/shaders_' + shader_type + '.cpp'); + mkdirp.sync(path.dirname(file_path)); + fs.writeFileSync(file_path, code); + console.warn('wrote file ' + file_path); }; diff --git a/common/headless_view.hpp b/common/headless_view.hpp index a203d477e..b3e1c11b9 100644 --- a/common/headless_view.hpp +++ b/common/headless_view.hpp @@ -29,14 +29,14 @@ private: private: -#ifdef LLMR_USE_CGL +#if LLMR_USE_CGL CGLContextObj gl_context; GLuint fbo = 0; GLuint fbo_depth_stencil = 0; GLuint fbo_color = 0; #endif -#ifdef LLMR_USE_GLX +#if LLMR_USE_GLX GLXContext gl_context = nullptr; XVisualInfo *x_info = nullptr; Display *x_display = nullptr; diff --git a/include/llmr/util/error.hpp b/include/llmr/util/error.hpp new file mode 100644 index 000000000..95106ff2c --- /dev/null +++ b/include/llmr/util/error.hpp @@ -0,0 +1,20 @@ +#ifndef LLMR_UTIL_ERROR +#define LLMR_UTIL_ERROR + +#include +#include + +namespace llmr { +namespace error { + +struct style_parse : std::exception { + inline style_parse(size_t offset, const char *msg) : offset(offset), msg(msg) {} + inline const char* what() const noexcept { return msg.c_str(); } + const size_t offset; + const std::string msg; +}; +} + +} + +#endif \ No newline at end of file diff --git a/include/llmr/util/io.hpp b/include/llmr/util/io.hpp index f1e560ffe..cdad97913 100644 --- a/include/llmr/util/io.hpp +++ b/include/llmr/util/io.hpp @@ -7,6 +7,7 @@ namespace llmr { namespace util { void write_file(const std::string &filename, const std::string &data); +std::string read_file(const std::string &filename); } } diff --git a/ios/Info.plist b/ios/Info.plist deleted file mode 100644 index 9c96d492a..000000000 --- a/ios/Info.plist +++ /dev/null @@ -1,47 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${PRODUCT_NAME} - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIdentifier - com.mapbox.${PRODUCT_NAME:rfc1034identifier} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.0.1 - CFBundleSignature - LLMR - CFBundleVersion - 0.0.1 - LSRequiresIPhoneOS - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - (c) 2014 Mapbox - - diff --git a/ios/MBXAppDelegate.h b/ios/MBXAppDelegate.h deleted file mode 100644 index 102343332..000000000 --- a/ios/MBXAppDelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// MBXAppDelegate.h -// ios -// -// Created by Justin R. Miller on 1/27/14. -// -// - -#import - -@interface MBXAppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - -@end \ No newline at end of file diff --git a/ios/MBXAppDelegate.m b/ios/MBXAppDelegate.m deleted file mode 100644 index 0fbcc6e81..000000000 --- a/ios/MBXAppDelegate.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// MBXAppDelegate.m -// ios -// -// Created by Justin R. Miller on 1/27/14. -// -// - -#import "MBXAppDelegate.h" - -#import "MBXViewController.h" - -@implementation MBXAppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.window.rootViewController = [MBXViewController new]; - [self.window makeKeyAndVisible]; - - return YES; -} - -@end diff --git a/ios/MBXViewController.h b/ios/MBXViewController.h deleted file mode 100644 index 924d3af60..000000000 --- a/ios/MBXViewController.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface MBXViewController : UIViewController - -@end diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm deleted file mode 100644 index 33e2f6e5e..000000000 --- a/ios/MBXViewController.mm +++ /dev/null @@ -1,214 +0,0 @@ -#import "MBXViewController.h" - -#import "MGLMapView.h" - -#import "../common/settings_nsuserdefaults.hpp" - -#import - -@interface MBXViewController () - -@property (nonatomic) MGLMapView *mapView; -@property (nonatomic) BOOL debug; -@property (nonatomic) UIView *palette; -@property (nonatomic) CLLocationManager *locationManager; - -@end - -@implementation MBXViewController - -llmr::Settings_NSUserDefaults *settings = nullptr; - -#pragma mark - Setup - -- (id)init -{ - self = [super init]; - - if (self) - { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveState:) name:UIApplicationDidEnterBackgroundNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restoreState:) name:UIApplicationWillEnterForegroundNotification object:nil]; - } - - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds]; - self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self.view addSubview:self.mapView]; - - self.mapView.viewControllerForLayoutGuides = self; - - settings = new llmr::Settings_NSUserDefaults(); - [self restoreState:nil]; - - [self setupDebugUI]; - - self.locationManager = [CLLocationManager new]; - self.locationManager.delegate = self; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" - -- (void)saveState:(NSNotification *)notification -{ - if (self.mapView && settings) - { - settings->longitude = self.mapView.centerCoordinate.longitude; - settings->latitude = self.mapView.centerCoordinate.latitude; - settings->zoom = self.mapView.zoomLevel; - settings->angle = self.mapView.direction; - settings->debug = self.mapView.isDebugActive; - settings->save(); - } -} - -- (void)restoreState:(NSNotification *)notification -{ - if (self.mapView && settings) { - settings->load(); - [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(settings->latitude, settings->longitude) zoomLevel:settings->zoom animated:NO]; - self.mapView.direction = settings->angle; - [self.mapView setDebugActive:settings->debug]; - } -} - -#pragma clang diagnostic pop - -- (void)setupDebugUI -{ - UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapGesture:)]; - singleTap.numberOfTapsRequired = 1; - [self.mapView addGestureRecognizer:singleTap]; - - NSArray *selectorNames = @[ @"unrotate", @"resetPosition", @"toggleDebug", @"toggleStyle", @"locateUser" ]; - CGFloat buttonSize = 40; - CGFloat bufferSize = 20; - CGFloat alpha = 0.75; - CGFloat paletteWidth = buttonSize + (2 * bufferSize); - CGFloat paletteHeight = [selectorNames count] * (buttonSize + bufferSize) + bufferSize; - self.palette = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width - paletteWidth, - (self.view.bounds.size.height - paletteHeight) / 2, - paletteWidth, - paletteHeight)]; - self.palette.backgroundColor = [UIColor colorWithWhite:0 alpha:alpha]; - self.palette.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin; - self.palette.layer.cornerRadius = bufferSize; - [self.view addSubview:self.palette]; - for (NSString *selectorName in selectorNames) - { - UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; - button.frame = CGRectMake(bufferSize, - ([selectorNames indexOfObject:selectorName] * (buttonSize + bufferSize)) + bufferSize, - buttonSize, - buttonSize); - [button setImage:[UIImage imageNamed:[selectorName stringByAppendingString:@".png"]] forState:UIControlStateNormal]; - [button addTarget:self action:NSSelectorFromString(selectorName) forControlEvents:UIControlEventTouchUpInside]; - [self.palette addSubview:button]; - } -} - -- (NSUInteger)supportedInterfaceOrientations -{ - return UIInterfaceOrientationMaskAll; -} - -#pragma mark - Debugging UI - -- (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap -{ - if (singleTap.state == UIGestureRecognizerStateEnded) - { - [self togglePalette]; - } -} - -- (void)togglePalette -{ - if (self.palette.alpha < 1) - { - self.palette.userInteractionEnabled = YES; - - [UIView animateWithDuration:0.25 animations:^(void) - { - self.palette.alpha = 1; - }]; - } - else - { - self.palette.userInteractionEnabled = NO; - - [UIView animateWithDuration:0.25 animations:^(void) - { - self.palette.alpha = 0; - }]; - } -} - -- (void)unrotate -{ - [self.mapView resetNorth]; -} - -- (void)resetPosition -{ - [self.mapView resetPosition]; -} - -- (void)toggleDebug -{ - [self.mapView toggleDebug]; - - self.debug = ! self.debug; -} - -- (void)toggleStyle -{ - [self.mapView toggleStyle]; -} - -- (void)locateUser -{ - [self.locationManager startUpdatingLocation]; -} - -#pragma mark - Destruction - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - if (settings) - { - [self saveState:nil]; - delete settings; - settings = nullptr; - } -} - -#pragma mark - User location - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" - -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations -{ - CLLocation *latestLocation = locations.lastObject; - - if ([latestLocation distanceFromLocation:[[CLLocation alloc] initWithLatitude:self.mapView.centerCoordinate.latitude longitude:self.mapView.centerCoordinate.longitude]] > 100) - { - [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(latestLocation.coordinate.latitude, latestLocation.coordinate.longitude) zoomLevel:17 animated:YES]; - } - - [self.locationManager stopUpdatingLocation]; -} - -#pragma clang diagnostic pop - -@end diff --git a/ios/img/Default-568h@2x.png b/ios/img/Default-568h@2x.png deleted file mode 100644 index 0891b7aab..000000000 Binary files a/ios/img/Default-568h@2x.png and /dev/null differ diff --git a/ios/img/Icon-40.png b/ios/img/Icon-40.png deleted file mode 100644 index eca13393e..000000000 Binary files a/ios/img/Icon-40.png and /dev/null differ diff --git a/ios/img/Icon-40@2x.png b/ios/img/Icon-40@2x.png deleted file mode 100644 index 070d03753..000000000 Binary files a/ios/img/Icon-40@2x.png and /dev/null differ diff --git a/ios/img/Icon-60.png b/ios/img/Icon-60.png deleted file mode 100644 index ff4c6ab4b..000000000 Binary files a/ios/img/Icon-60.png and /dev/null differ diff --git a/ios/img/Icon-60@2x.png b/ios/img/Icon-60@2x.png deleted file mode 100644 index b7f25955f..000000000 Binary files a/ios/img/Icon-60@2x.png and /dev/null differ diff --git a/ios/img/Icon-72.png b/ios/img/Icon-72.png deleted file mode 100644 index 0c876f664..000000000 Binary files a/ios/img/Icon-72.png and /dev/null differ diff --git a/ios/img/Icon-72@2x.png b/ios/img/Icon-72@2x.png deleted file mode 100644 index 6da408204..000000000 Binary files a/ios/img/Icon-72@2x.png and /dev/null differ diff --git a/ios/img/Icon-76.png b/ios/img/Icon-76.png deleted file mode 100644 index 895b4a176..000000000 Binary files a/ios/img/Icon-76.png and /dev/null differ diff --git a/ios/img/Icon-76@2x.png b/ios/img/Icon-76@2x.png deleted file mode 100644 index 7bc520897..000000000 Binary files a/ios/img/Icon-76@2x.png and /dev/null differ diff --git a/ios/img/Icon-Small-50.png b/ios/img/Icon-Small-50.png deleted file mode 100644 index 6d17da4b0..000000000 Binary files a/ios/img/Icon-Small-50.png and /dev/null differ diff --git a/ios/img/Icon-Small-50@2x.png b/ios/img/Icon-Small-50@2x.png deleted file mode 100644 index ac4ec1928..000000000 Binary files a/ios/img/Icon-Small-50@2x.png and /dev/null differ diff --git a/ios/img/Icon-Small.png b/ios/img/Icon-Small.png deleted file mode 100644 index aecbbc8a1..000000000 Binary files a/ios/img/Icon-Small.png and /dev/null differ diff --git a/ios/img/Icon-Small@2x.png b/ios/img/Icon-Small@2x.png deleted file mode 100644 index 7773852e7..000000000 Binary files a/ios/img/Icon-Small@2x.png and /dev/null differ diff --git a/ios/img/Icon-Spotlight-40.png b/ios/img/Icon-Spotlight-40.png deleted file mode 100644 index eca13393e..000000000 Binary files a/ios/img/Icon-Spotlight-40.png and /dev/null differ diff --git a/ios/img/Icon-Spotlight-40@2x.png b/ios/img/Icon-Spotlight-40@2x.png deleted file mode 100644 index 070d03753..000000000 Binary files a/ios/img/Icon-Spotlight-40@2x.png and /dev/null differ diff --git a/ios/img/Icon.png b/ios/img/Icon.png deleted file mode 100644 index 9ca8194ee..000000000 Binary files a/ios/img/Icon.png and /dev/null differ diff --git a/ios/img/Icon@2x.png b/ios/img/Icon@2x.png deleted file mode 100644 index 7c2e8ba03..000000000 Binary files a/ios/img/Icon@2x.png and /dev/null differ diff --git a/ios/img/iTunesArtwork b/ios/img/iTunesArtwork deleted file mode 100644 index ac6a0c58e..000000000 Binary files a/ios/img/iTunesArtwork and /dev/null differ diff --git a/ios/img/iTunesArtwork.png b/ios/img/iTunesArtwork.png deleted file mode 100644 index b10824b04..000000000 Binary files a/ios/img/iTunesArtwork.png and /dev/null differ diff --git a/ios/img/iTunesArtwork@2x b/ios/img/iTunesArtwork@2x deleted file mode 100644 index fae1dad8b..000000000 Binary files a/ios/img/iTunesArtwork@2x and /dev/null differ diff --git a/ios/img/iTunesArtwork@2x.png b/ios/img/iTunesArtwork@2x.png deleted file mode 100644 index fdee900aa..000000000 Binary files a/ios/img/iTunesArtwork@2x.png and /dev/null differ diff --git a/ios/img/locateUser.png b/ios/img/locateUser.png deleted file mode 100644 index e0599e542..000000000 Binary files a/ios/img/locateUser.png and /dev/null differ diff --git a/ios/img/resetPosition.png b/ios/img/resetPosition.png deleted file mode 100644 index 81269cd4f..000000000 Binary files a/ios/img/resetPosition.png and /dev/null differ diff --git a/ios/img/toggleDebug.png b/ios/img/toggleDebug.png deleted file mode 100644 index aa5e3042f..000000000 Binary files a/ios/img/toggleDebug.png and /dev/null differ diff --git a/ios/img/toggleStyle.png b/ios/img/toggleStyle.png deleted file mode 100644 index 59a6f330f..000000000 Binary files a/ios/img/toggleStyle.png and /dev/null differ diff --git a/ios/img/unrotate.png b/ios/img/unrotate.png deleted file mode 100644 index 63361e99d..000000000 Binary files a/ios/img/unrotate.png and /dev/null differ diff --git a/ios/llmr-app.gyp b/ios/llmr-app.gyp deleted file mode 100644 index aeccd573f..000000000 --- a/ios/llmr-app.gyp +++ /dev/null @@ -1,70 +0,0 @@ -{ - 'includes': [ - '../common.gypi', - '../config.gypi' - ], - 'targets': [ - { - "target_name": "iosapp", - "product_name": "Mapbox GL", - "type": "executable", - "sources": [ - "./main.m", - "./MBXAppDelegate.h", - "./MBXAppDelegate.m", - "./MBXViewController.h", - "./MBXViewController.mm", - ' - -#import "MBXAppDelegate.h" - -int main(int argc, char * argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([MBXAppDelegate class])); - } -} diff --git a/ios/mapbox-gl-cocoa b/ios/mapbox-gl-cocoa index 698f31b3c..93615fe8a 160000 --- a/ios/mapbox-gl-cocoa +++ b/ios/mapbox-gl-cocoa @@ -1 +1 @@ -Subproject commit 698f31b3c777b50839aa116340614f6f18d5087a +Subproject commit 93615fe8a3123332d608eaae0a9b804059bd8581 diff --git a/llmr.gyp b/llmr.gyp index ad92da645..9468a5b5c 100644 --- a/llmr.gyp +++ b/llmr.gyp @@ -15,9 +15,9 @@ 'body { font-family: Helvetica; }\n' + + '\n' + + '\n' + + ' \n' + + ' \n' + + ' \n' + + '\n'; + +var dir = fs.readdirSync('./test/fixtures/styles').filter(function(name) { + return name.match(/\.info\.json$/); +}).forEach(function(name) { + var info = require(path.join(path.resolve('.'), './test/fixtures/styles', name)); + var base = path.basename(name, '.info.json'); + + html += + '\n' + + ' \n' + + ' \n' + + ' \n' + + '\n' + ; +}); + +html += "gcc and thread->clang for + # some limited coverage + if [[ ${BUILDTYPE} == "Debug" ]]; then + if [[ ${CXX} == "g++" ]]; then + export CXXFLAGS="-fsanitize=address ${CXXFLAGS}" + export CFLAGS="-fsanitize=address ${CFLAGS}" + export LDFLAGS="-fsanitize=address ${LDFLAGS}" + elif [[ ${CXX} == "clang++" ]]; then + export CXXFLAGS="-fsanitize=thread -fPIC ${CXXFLAGS}" + export CFLAGS="-fsanitize=thread ${CFLAGS}" + export LDFLAGS="-fsanitize=thread -pie ${LDFLAGS}" + fi + fi +fi + +# turn off a few warnings +export CXXFLAGS="-Wno-unknown-warning-option -Wno-unused-local-typedefs -Wno-unknown-pragmas ${CXXFLAGS}"; diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh new file mode 100755 index 000000000..be65356ba --- /dev/null +++ b/scripts/run_tests.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +BUILDTYPE="${BUILDTYPE:-Release}" + +cd build/${BUILDTYPE} + +for TEST in ./test_* ; do + ${TEST} +done diff --git a/scripts/setup_travis.sh b/scripts/setup_travis.sh index 3b819ea81..128f6bbf7 100755 --- a/scripts/setup_travis.sh +++ b/scripts/setup_travis.sh @@ -3,15 +3,6 @@ set -e set -o pipefail -# enable testing locally (not on travis) -if [[ "${TRAVIS_OS_NAME:-false}" == false ]]; then - if [[ $(uname -s) == "Darwin" ]]; then - TRAVIS_OS_NAME="osx" - elif [[ $(uname -s) == "Linux" ]]; then - TRAVIS_OS_NAME="linux" - fi -fi - if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then if [[ `lsb_release -r` =~ "12.04" ]]; then @@ -19,36 +10,10 @@ if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then fi sudo apt-get update -y sudo apt-get -y install gcc-4.8 g++-4.8 - sudo apt-get -y install git build-essential zlib1g-dev automake libtool xutils-dev make cmake pkg-config + sudo apt-get -y install git build-essential zlib1g-dev automake libtool xutils-dev make cmake pkg-config python-pip sudo apt-get -y install libxi-dev libglu1-mesa-dev x11proto-randr-dev x11proto-xext-dev libxrandr-dev x11proto-xf86vidmode-dev libxxf86vm-dev libxcursor-dev - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - - # use g++ that supports c++11 - if [[ ${CXX} == "g++" ]]; then - export CXX="g++-4.8" ; - fi - - # If building in debug then turn on sanitizers. - # They should both work with latest g++/clang++ - # but it's not worth a standalone matrix so here - # we just test address->gcc and thread->clang for - # some limited coverage - if [[ ${BUILDTYPE} == "Debug" ]]; then - if [[ ${CXX} == "g++" ]]; then - export CXXFLAGS="-fsanitize=address ${CXXFLAGS}" - export CFLAGS="-fsanitize=address ${CFLAGS}" - export LDFLAGS="-fsanitize=address ${LDFLAGS}" - elif [[ ${CXX} == "clang++" ]]; then - export CXXFLAGS="-fsanitize=thread -fPIC ${CXXFLAGS}" - export CFLAGS="-fsanitize=thread ${CFLAGS}" - export LDFLAGS="-fsanitize=thread -pie ${LDFLAGS}" - fi - fi + sudo pip install awscli elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then brew install autoconf automake libtool makedepend cmake pkg-config node git fi - -# turn off a few warnings -export CXXFLAGS="-Wno-unknown-warning-option -Wno-unused-local-typedefs -Wno-unknown-pragmas ${CXXFLAGS}"; diff --git a/setup-libraries.sh b/setup-libraries.sh index 3642d91ff..aa0360d98 100755 --- a/setup-libraries.sh +++ b/setup-libraries.sh @@ -96,6 +96,13 @@ cd ../../ elif [ ${UNAME} = 'Linux' ]; then +if [ ! -z "${TRAVIS:-}" ]; then + if aws s3 cp s3://mapbox-gl-testing/dependencies/build-cpp11-libstdcpp-gcc-x86_64-linux.tar.gz ./out/ ; then + rm -rf out/build-cpp11-libstdcpp-gcc-x86_64-linux + tar -xzf out/build-cpp11-libstdcpp-gcc-x86_64-linux.tar.gz + fi +fi + source Linux.sh if [ ! -f out/build-cpp11-libstdcpp-gcc-x86_64-linux/lib/libglfw3.a ] ; then ./scripts/build_glfw.sh ; fi if [ ! -f out/build-cpp11-libstdcpp-gcc-x86_64-linux/lib/libpng.a ] ; then ./scripts/build_png.sh ; fi @@ -104,6 +111,13 @@ source Linux.sh if [ ! -f out/build-cpp11-libstdcpp-gcc-x86_64-linux/lib/libcurl.a ] ; then ./scripts/build_curl.sh ; fi if [ ! -f out/build-cpp11-libstdcpp-gcc-x86_64-linux/lib/libboost_regex.a ] ; then ./scripts/build_boost.sh --with-regex ; fi +if [ ! -z "${TRAVIS:-}" ]; then + if ! tar --compare -zf out/build-cpp11-libstdcpp-gcc-x86_64-linux.tar.gz ; then + tar -zcf out/build-cpp11-libstdcpp-gcc-x86_64-linux.tar.gz out/build-cpp11-libstdcpp-gcc-x86_64-linux + aws s3 cp out/build-cpp11-libstdcpp-gcc-x86_64-linux.tar.gz s3://mapbox-gl-testing/dependencies/ + fi +fi + cd ../../ ./configure \ --pkg-config-root=`pwd`/mapnik-packaging/osx/out/build-cpp11-libstdcpp-gcc-x86_64-linux/lib/pkgconfig \ diff --git a/src/map/map.cpp b/src/map/map.cpp index b04f88a54..516e8fe03 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -491,15 +491,6 @@ void Map::render() { painter.drawClippingMasks(style->getActiveSources()); -#if defined(DEBUG) - // Generate debug information - size_t source_id = 0; - for (const std::shared_ptr &source : style->getActiveSources()) { - size_t count = source->getTileCount(); - debug.emplace_back(util::sprintf<100>("source %d: %d\n", source_id, count)); - source_id++; - } -#endif // Actually render the layers if (debug::renderTree) { std::cout << "{" << std::endl; indent++; } renderLayers(style->layers); @@ -515,10 +506,6 @@ void Map::render() { painter.renderMatte(); -#if defined(DEBUG) - painter.renderDebugText(debug); -#endif - // Schedule another rerender when we definitely need a next frame. if (transform.needsTransition() || style->hasTransitions()) { update(); diff --git a/src/style/style.cpp b/src/style/style.cpp index fc2364da8..006376172 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -102,6 +103,9 @@ void Style::loadJSON(const uint8_t *const data) { rapidjson::Document doc; doc.Parse<0>((const char *const)data); + if (doc.HasParseError()) { + throw error::style_parse(doc.GetErrorOffset(), doc.GetParseError()); + } StyleParser parser; parser.parse(const_cast(doc)); diff --git a/src/util/io.cpp b/src/util/io.cpp index bf519b057..1312b907b 100644 --- a/src/util/io.cpp +++ b/src/util/io.cpp @@ -1,8 +1,15 @@ #include #include +#include +#include +#include +#include -void llmr::util::write_file(const std::string &filename, const std::string &data) { +namespace llmr { +namespace util { + +void write_file(const std::string &filename, const std::string &data) { FILE *fd = fopen(filename.c_str(), "wb"); if (fd) { fwrite(data.data(), sizeof(std::string::value_type), data.size(), fd); @@ -11,3 +18,17 @@ void llmr::util::write_file(const std::string &filename, const std::string &data fprintf(stderr, "Failed to open file\n"); } } + +std::string read_file(const std::string &filename) { + std::ifstream file(filename); + if (file.good()) { + std::stringstream data; + data << file.rdbuf(); + return data.str(); + } else { + throw std::runtime_error("Cannot read file " + filename); + } +} + +} +} \ No newline at end of file diff --git a/test/fixtures/https/mapbox.s3.amazonaws.com/gl-glyphs-256/Open Sans Semibold, Arial Unicode MS Bold/0-255.pbf b/test/fixtures/glyphs/Open Sans Semibold, Arial Unicode MS Bold/0-255.pbf similarity index 100% rename from test/fixtures/https/mapbox.s3.amazonaws.com/gl-glyphs-256/Open Sans Semibold, Arial Unicode MS Bold/0-255.pbf rename to test/fixtures/glyphs/Open Sans Semibold, Arial Unicode MS Bold/0-255.pbf diff --git a/test/fixtures/result/out.png b/test/fixtures/result/out.png deleted file mode 100644 index aff3dccbb..000000000 Binary files a/test/fixtures/result/out.png and /dev/null differ diff --git a/test/fixtures/https/www.mapbox.com/mapbox-gl-styles/sprites/outdoors.json b/test/fixtures/sprites/outdoors.json similarity index 100% rename from test/fixtures/https/www.mapbox.com/mapbox-gl-styles/sprites/outdoors.json rename to test/fixtures/sprites/outdoors.json diff --git a/test/fixtures/https/www.mapbox.com/mapbox-gl-styles/sprites/outdoors.png b/test/fixtures/sprites/outdoors.png similarity index 100% rename from test/fixtures/https/www.mapbox.com/mapbox-gl-styles/sprites/outdoors.png rename to test/fixtures/sprites/outdoors.png diff --git a/test/fixtures/styles/0.expected.png b/test/fixtures/styles/0.expected.png new file mode 100644 index 000000000..34e984cce Binary files /dev/null and b/test/fixtures/styles/0.expected.png differ diff --git a/test/fixtures/styles/0.info.json b/test/fixtures/styles/0.info.json new file mode 100644 index 000000000..3501d30ed --- /dev/null +++ b/test/fixtures/styles/0.info.json @@ -0,0 +1,8 @@ +{ + "zoom": 0, + "latitude": 0, + "longitude": 0, + "angle": 0, + "width": 512, + "height": 512 +} diff --git a/test/fixtures/styles/0.style.json b/test/fixtures/styles/0.style.json new file mode 100644 index 000000000..06d7a1db1 --- /dev/null +++ b/test/fixtures/styles/0.style.json @@ -0,0 +1,34 @@ +{ + "version": 3, + "sources": { + "mapbox": { + "type": "vector", + "url": "tiles/%d-%d-%d.vector.pbf", + "tileSize": 512, + "maxZoom": 14 + } + }, + "layers": [ + { + "id": "background", + "render": { + "type": "background" + }, + "style": { + "background-color": "red" + } + }, + { + "id": "water", + "source": "mapbox", + "source-layer": "water", + "render": { + "type": "fill" + }, + "style": { + "fill-color": "blue", + "fill-antialias": false + } + } + ] +} diff --git a/test/fixtures/styles/1.expected.png b/test/fixtures/styles/1.expected.png new file mode 100644 index 000000000..d34c46a6c Binary files /dev/null and b/test/fixtures/styles/1.expected.png differ diff --git a/test/fixtures/styles/1.info.json b/test/fixtures/styles/1.info.json new file mode 100644 index 000000000..3501d30ed --- /dev/null +++ b/test/fixtures/styles/1.info.json @@ -0,0 +1,8 @@ +{ + "zoom": 0, + "latitude": 0, + "longitude": 0, + "angle": 0, + "width": 512, + "height": 512 +} diff --git a/test/fixtures/styles/1.style.json b/test/fixtures/styles/1.style.json new file mode 100644 index 000000000..d35c4bc0f --- /dev/null +++ b/test/fixtures/styles/1.style.json @@ -0,0 +1,33 @@ +{ + "version": 3, + "sources": { + "mapbox": { + "type": "vector", + "url": "tiles/%d-%d-%d.vector.pbf", + "tileSize": 512, + "maxZoom": 14 + } + }, + "layers": [ + { + "id": "background", + "render": { + "type": "background" + }, + "style": { + "background-color": "red" + } + }, + { + "id": "water", + "source": "mapbox", + "source-layer": "water", + "render": { + "type": "fill" + }, + "style": { + "fill-color": "blue" + } + } + ] +} diff --git a/test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/0/0/0.vector.pbf b/test/fixtures/tiles/0-0-0.vector.pbf similarity index 100% rename from test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/0/0/0.vector.pbf rename to test/fixtures/tiles/0-0-0.vector.pbf diff --git a/test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/1/1.vector.pbf b/test/fixtures/tiles/2-1-1.vector.pbf similarity index 100% rename from test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/1/1.vector.pbf rename to test/fixtures/tiles/2-1-1.vector.pbf diff --git a/test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/1/2.vector.pbf b/test/fixtures/tiles/2-1-2.vector.pbf similarity index 100% rename from test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/1/2.vector.pbf rename to test/fixtures/tiles/2-1-2.vector.pbf diff --git a/test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/2/1.vector.pbf b/test/fixtures/tiles/2-2-1.vector.pbf similarity index 100% rename from test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/2/1.vector.pbf rename to test/fixtures/tiles/2-2-1.vector.pbf diff --git a/test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/2/2.vector.pbf b/test/fixtures/tiles/2-2-2.vector.pbf similarity index 100% rename from test/fixtures/http/api.tiles.mapbox.com/v3/mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5/2/2/2.vector.pbf rename to test/fixtures/tiles/2-2-2.vector.pbf diff --git a/test/headless.cpp b/test/headless.cpp index 88169d8da..0ed6e0a09 100644 --- a/test/headless.cpp +++ b/test/headless.cpp @@ -3,24 +3,39 @@ #include #include #include -#include +#include + +#include #include "../common/headless_view.hpp" -#include -#include - const std::string base_directory = []{ std::string fn = __FILE__; fn.erase(fn.find_last_of("/")); return fn; }(); -TEST(Headless, initialize) { - const unsigned int width = 1024; - const unsigned int height = 768; +class HeadlessTest : public ::testing::TestWithParam {}; - llmr::util::timer timer; +TEST_P(HeadlessTest, render) { + const char *base = GetParam(); + + const std::string style = llmr::util::read_file(base_directory + "/fixtures/styles/" + base + ".style.json"); + const std::string info = llmr::util::read_file(base_directory + "/fixtures/styles/" + base + ".info.json"); + const std::string expected_image = base_directory + "/fixtures/styles/" + base + ".expected.png"; + const std::string actual_image = base_directory + "/fixtures/styles/" + base + ".actual.png"; + + // Parse settings. + rapidjson::Document doc; + doc.Parse<0>((const char *const)info.c_str()); + ASSERT_EQ(false, doc.HasParseError()); + + const double zoom = doc.HasMember("zoom") ? doc["zoom"].GetDouble() : 0; + const double angle = doc.HasMember("angle") ? doc["angle"].GetDouble() : 0; + const double longitude = doc.HasMember("longitude") ? doc["longitude"].GetDouble() : 0; + const double latitude = doc.HasMember("latitude") ? doc["latitude"].GetDouble() : 0; + const unsigned int width = doc.HasMember("width") ? doc["width"].GetUint() : 0; + const unsigned int height = doc.HasMember("height") ? doc["height"].GetUint() : 0; // Setup OpenGL llmr::HeadlessView view; @@ -29,42 +44,27 @@ TEST(Headless, initialize) { view.resize(width, height); map.resize(width, height); - timer.report("map setup"); + map.setStyleJSON(style); - std::ifstream stylefile("./style.min.js"); - ASSERT_TRUE(stylefile.good()); - std::stringstream stylejson; - stylejson << stylefile.rdbuf(); - - map.setStyleJSON(stylejson.str()); - - timer.report("map style"); - - map.setLonLatZoom(0, 0, 2); - map.setAngle(0); + map.setLonLatZoom(longitude, latitude, zoom); + map.setAngle(angle); map.setDebug(false); // Run the loop. It will terminate when we don't have any further listeners. map.run(); - timer.report("map loop"); + const std::unique_ptr pixels(new uint32_t[width * height]); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); - uint32_t *pixels = new uint32_t[width * height]; + const std::string image = llmr::util::compress_png(width, height, pixels.get(), true); + llmr::util::write_file(actual_image, image); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - std::string result = llmr::util::compress_png(width, height, pixels, true); - llmr::util::write_file("out.png", result); - - std::ifstream imagefile(base_directory + "/fixtures/result/out.png"); - ASSERT_TRUE(imagefile.good()); - std::stringstream image; - image << imagefile.rdbuf(); - llmr::util::Image reference(image.str(), true); - - ASSERT_EQ(reference.getWidth(), width); - ASSERT_EQ(reference.getHeight(), height); - ASSERT_EQ(0, std::memcmp(pixels, reference.getData(), width * height * 4)); - - delete[] pixels; + const std::string expected_image_data(llmr::util::read_file(expected_image)); + const llmr::util::Image expected(expected_image_data, true); + ASSERT_EQ(width, expected.getWidth()); + ASSERT_EQ(height, expected.getHeight()); + ASSERT_EQ(0, std::memcmp(pixels.get(), expected.getData(), width * height * 4)); } + +INSTANTIATE_TEST_CASE_P(Headless, HeadlessTest, + ::testing::Values("0", "1")); diff --git a/travis/travis-resources.template b/travis/travis-resources.template new file mode 100644 index 000000000..afe0478e3 --- /dev/null +++ b/travis/travis-resources.template @@ -0,0 +1,74 @@ + +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "mapbox-gl-native travis resources", + "Resources": { + "BuildUser": { + "Type": "AWS::IAM::User", + "Properties": { + "Policies": [ + { + "PolicyName": "list", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:ListBucket" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox-gl-testing" + ] + } + ] + } + }, + { + "PolicyName": "build", + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Effect": "Allow", + "Resource": [ + "arn:aws:s3:::mapbox-gl-testing/*" + ] + } + ] + } + } + ] + } + }, + "BuildUserKey": { + "Type": "AWS::IAM::AccessKey", + "Properties": { + "UserName": { + "Ref": "BuildUser" + } + } + } + }, + "Outputs": { + "AccessKeyId": { + "Value": { + "Ref": "BuildUserKey" + } + }, + "SecretAccessKey": { + "Value": { + "Fn::GetAtt": [ + "BuildUserKey", + "SecretAccessKey" + ] + } + } + } +} +
ActualExpectedInfo
\n' + + '

' + base + '

\n' + + '
    \n' + + '
  • zoom: ' + (info.zoom || 0) + '
  • \n' + + '
  • latitude: ' + (info.latitude || 0) + '
  • \n' + + '
  • longitude: ' + (info.longitude || 0) + '
  • \n' + + '
  • angle: ' + (info.angle || 0) + '
  • \n' + + '
  • width: ' + (info.width || 0) + '
  • \n' + + '
  • height: ' + (info.height || 0) + '
  • \n' + + '
\n' + + '