This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository mapnik.

commit 9872e31f882054aa3d108bdfebfbaab0eaabb8b4
Author: Bas Couwenberg <sebas...@xs4all.nl>
Date:   Tue Nov 3 23:24:26 2015 +0100

    Imported Upstream version 3.0.9~rc1+ds
---
 .travis.yml                                        |   8 +-
 demo/python/rundemo.py                             |   9 +-
 demo/simple-renderer/render.py                     |   4 +-
 include/mapnik/json/error_handler.hpp              |  36 ++-
 .../json/extract_bounding_box_grammar_impl.hpp     |  32 +--
 include/mapnik/json/feature_collection_grammar.hpp |  16 +-
 .../json/feature_collection_grammar_impl.hpp       |  53 +----
 include/mapnik/json/geometry_grammar.hpp           |   2 +-
 include/mapnik/json/geometry_grammar_impl.hpp      |  23 +-
 include/mapnik/util/variant.hpp                    |  65 +++++-
 include/mapnik/value.hpp                           | 121 +++++++---
 plugins/input/csv/csv_datasource.cpp               |   1 -
 plugins/input/geojson/geojson_datasource.cpp       |  10 +-
 plugins/input/geojson/geojson_index_featureset.cpp |   6 +-
 .../geojson/geojson_memory_index_featureset.cpp    |   7 +-
 src/image.cpp                                      |   5 +-
 test/unit/core/box2d_test.cpp                      |   1 -
 test/unit/core/comparison_test.cpp                 |  69 +++++-
 test/unit/core/conversions_test.cpp                |   2 -
 test/unit/core/copy_move_test.cpp                  |   3 -
 test/unit/core/params_test.cpp                     |   2 -
 test/unit/datasource/csv.cpp                       | 245 ++++++---------------
 test/unit/datasource/ds_test_util.hpp              | 172 +++++++++++++++
 test/unit/datasource/geojson.cpp                   |  21 +-
 test/unit/datasource/ogr.cpp                       |   1 -
 test/unit/datasource/postgis.cpp                   |  94 ++++++++
 test/unit/datasource/spatial_index.cpp             |   3 -
 test/unit/font/fontset_runtime_test.cpp            |  10 -
 test/unit/geometry/geometry.cpp                    |   1 -
 test/unit/geometry/geometry_converters_test.cpp    | 192 ----------------
 test/unit/geometry/geometry_envelope_test.cpp      |   2 -
 test/unit/geometry/geometry_is_simple.cpp          |   1 -
 test/unit/geometry/geometry_is_valid.cpp           |   1 -
 test/unit/geometry/geometry_reprojection.cpp       |   4 -
 test/unit/geometry/label_algo_test.cpp             |  64 ++----
 test/unit/imaging/image.cpp                        |  26 +--
 test/unit/imaging/image_io_test.cpp                |   2 -
 test/unit/imaging/image_set_pixel.cpp              |   4 +-
 test/unit/imaging/image_view.cpp                   |   2 +-
 test/unit/imaging/tiff_io.cpp                      |   2 -
 test/unit/imaging/webp_io.cpp                      |   3 +-
 test/unit/pixel/agg_blend_src_over_test.cpp        |   3 -
 test/unit/serialization/wkb_formats_test.cpp       |   3 -
 test/unit/serialization/xml_parser_trim.cpp        |   4 +-
 test/unit/svg/svg_parser_test.cpp                  |   4 +-
 test/unit/symbolizer/symbolizer_test.cpp           |   2 -
 test/unit/vertex_adapter/clipping_test.cpp         |   2 -
 test/unit/vertex_adapter/line_offset_test.cpp      |   6 +-
 test/unit/vertex_adapter/offset_converter.cpp      |   5 -
 .../vertex_adapter/simplify_converters_test.cpp    |  14 +-
 utils/mapnik-index/process_geojson_file.cpp        |  11 +-
 51 files changed, 713 insertions(+), 666 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 01ff425..656ac25 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -46,14 +46,18 @@ before_install:
 
 install:
  - if [[ $(uname -s) == 'Linux' ]]; then
-     psql -U postgres -c 'create database template_postgis;' -U postgres;
-     psql -U postgres -c 'create extension postgis;' -d template_postgis -U 
postgres;
      export CXX="ccache clang++-3.5 -Qunused-arguments";
      export CC="ccache clang-3.5 -Qunused-arguments";
      export PYTHONPATH=$(pwd)/mason_packages/.link/lib/python2.7/site-packages;
    else
+     brew rm postgis --force;
+     brew install postgis --force;
+     pg_ctl -w start -l postgres.log --pgdata /usr/local/var/postgres;
+     createuser -s postgres;
      export PYTHONPATH=$(pwd)/mason_packages/.link/lib/python/site-packages;
    fi
+ - psql -c 'create database template_postgis;' -U postgres;
+ - psql -c 'create extension postgis;' -d template_postgis -U postgres;
  - if [[ ${COVERAGE} == true ]]; then
      PYTHONUSERBASE=$(pwd)/mason_packages/.link pip install --user 
cpp-coveralls;
    fi
diff --git a/demo/python/rundemo.py b/demo/python/rundemo.py
index 65ebe6a..7e6c42c 100755
--- a/demo/python/rundemo.py
+++ b/demo/python/rundemo.py
@@ -19,10 +19,9 @@
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
+from __future__ import print_function
 import sys
 from os import path
-
 import mapnik
 
 # Instanciate a map, giving it a width and height. Remember: the word "map" is
@@ -370,11 +369,11 @@ if  mapnik.has_cairo():
     mapnik.render_to_file(m,'demo_cairo_argb32.png','ARGB32')
     images_.append('demo_cairo_argb.png')
 
-print "\n\n", len(images_), "maps have been rendered in the current directory:"
+print ("\n\n", len(images_), "maps have been rendered in the current 
directory:")
 
 for im_ in images_:
-    print "-", im_
+    print ("-", im_)
 
-print "\n\nHave a look!\n\n"
+print ("\n\nHave a look!\n\n")
 
 mapnik.save_map(m,"map.xml")
diff --git a/demo/simple-renderer/render.py b/demo/simple-renderer/render.py
index 6ab075d..49bf721 100755
--- a/demo/simple-renderer/render.py
+++ b/demo/simple-renderer/render.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-
+from __future__ import print_function
 import sys
 import mapnik
 
@@ -19,5 +19,5 @@ elif len(sys.argv) == 3:
 elif len(sys.argv) == 5:
     render(sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4]))
 else:
-    print "usage: %s style_file [output_file] [width height]" % sys.argv[0]
+    print ("usage: %s style_file [output_file] [width height]" % sys.argv[0])
     sys.exit(1)
diff --git a/include/mapnik/json/error_handler.hpp 
b/include/mapnik/json/error_handler.hpp
index 90d64af..02b38cf 100644
--- a/include/mapnik/json/error_handler.hpp
+++ b/include/mapnik/json/error_handler.hpp
@@ -23,29 +23,43 @@
 #ifndef MAPNIK_JSON_ERROR_HANDLER_HPP
 #define MAPNIK_JSON_ERROR_HANDLER_HPP
 
-#include <string>
-#include <sstream>
+#include <mapnik/config.hpp>
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wsign-conversion"
+#include <boost/spirit/home/qi.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #pragma GCC diagnostic pop
+// mapnik
+#include <mapnik/debug.hpp>
+// stl
+#include <cassert>
+#include <string>
+#include <sstream>
+
 
 namespace mapnik { namespace json {
 
 template <typename Iterator>
 struct error_handler
 {
-    using result_type = void;
-    void operator() (
-        Iterator, Iterator,
-        Iterator err_pos, boost::spirit::info const& what) const
+    using result_type = boost::spirit::qi::error_handler_result;
+    result_type operator() (
+        Iterator,
+        Iterator end,
+        Iterator err_pos,
+        boost::spirit::info const& what) const
     {
+#ifdef MAPNIK_LOG
         std::stringstream s;
-        auto start = err_pos;
-        std::advance(err_pos,16);
-        auto end = err_pos;
-        s << "Mapnik geojson parsing error:" << what << " expected but got: " 
<< std::string(start, end);
-        throw std::runtime_error(s.str());
+        using difference_type = typename 
std::iterator_traits<Iterator>::difference_type;
+        auto start_err = err_pos;
+        std::advance(err_pos, std::min(std::distance(err_pos, end), 
difference_type(16)));
+        auto end_err = err_pos;
+        assert(end_err <= end);
+        s << "Mapnik GeoJSON parsing error:" << what << " expected but got: " 
<< std::string(start_err, end_err);
+        MAPNIK_LOG_ERROR(error_handler) << s.str();
+#endif
+        return boost::spirit::qi::fail;
     }
 };
 
diff --git a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp 
b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
index fc08584..a6d3218 100644
--- a/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
+++ b/include/mapnik/json/extract_bounding_box_grammar_impl.hpp
@@ -56,6 +56,7 @@ extract_bounding_box_grammar<Iterator, 
ErrorHandler>::extract_bounding_box_gramm
     qi::eps_type eps;
     qi::raw_type raw;
     qi::char_type char_;
+    qi::no_skip_type no_skip;
     boost::spirit::repository::qi::iter_pos_type iter_pos;
     using qi::fail;
     using qi::on_error;
@@ -63,23 +64,26 @@ extract_bounding_box_grammar<Iterator, 
ErrorHandler>::extract_bounding_box_gramm
     start = features(_r1)
         ;
 
-    features = iter_pos[_a = _1] >> -(lit('{')
-                                      >> *((json.key_value - 
lit("\"features\"")) >> lit(','))
-                                      >> lit("\"features\"")
-                                      >> lit(':'))
-                                 >> lit('[') >> (feature(_r1,_a) % lit(',')) 
>> lit(']')
+    features = no_skip[iter_pos[_a = _1]] >> -(lit('{')
+                                               >> *((json.key_value - 
lit("\"features\"")) >> lit(','))
+                                               >> lit("\"features\"")
+                                               >> lit(':'))
+                                          >> lit('[') >> (feature(_r1,_a) % 
lit(',')) >> lit(']')
         ;
 
     feature = raw[lit('{')[_a = 1]
-                  >> *(eps(_a > 0) >> (lit('{')[_a += 1]
-                                       |
-                                       lit('}')[_a -=1]
-                                       |
-                                       coords[_b = _1]
-                                       |
-                                       json.string_
-                                       |
-                                       char_))][push_box(_r1, _r2, _b, _1)]
+                  >> *(eps(_a > 0) >> (
+                           lit("\"FeatureCollection\"") > eps(false) // fail 
if nested FeatureCollection
+                           |
+                           lit('{')[_a += 1]
+                           |
+                           lit('}')[_a -= 1]
+                           |
+                           coords[_b = _1]
+                           |
+                           json.string_
+                           |
+                           char_))][push_box(_r1, _r2, _b, _1)]
         ;
 
     coords = lit("\"coordinates\"")
diff --git a/include/mapnik/json/feature_collection_grammar.hpp 
b/include/mapnik/json/feature_collection_grammar.hpp
index 5f62cdf..c71801c 100644
--- a/include/mapnik/json/feature_collection_grammar.hpp
+++ b/include/mapnik/json/feature_collection_grammar.hpp
@@ -59,27 +59,26 @@ struct apply_feature_callback
     }
 };
 
-template <typename Iterator, typename FeatureType, typename FeatureCallback = 
default_feature_callback>
+template <typename Iterator, typename FeatureType, typename FeatureCallback = 
default_feature_callback, typename ErrorHandler = error_handler<Iterator> >
 struct feature_collection_grammar :
         qi::grammar<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback &), space_type>
 {
     feature_collection_grammar(mapnik::transcoder const& tr);
     // grammars
-    feature_grammar<Iterator,FeatureType> feature_g;
-    //geometry_grammar<Iterator> geometry_g;
+    feature_grammar<Iterator, FeatureType, ErrorHandler> feature_g;
     // rules
     qi::rule<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback&), space_type> start; // START
     qi::rule<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback&), space_type> feature_collection;
     qi::rule<Iterator, space_type> type;
     qi::rule<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback&), space_type> features;
     qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& 
ctx, std::size_t, FeatureCallback&), space_type> feature;
-    //qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& 
ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry;
     // phoenix functions
-    //phoenix::function<json::set_geometry_impl> set_geometry;
     phoenix::function<apply_feature_callback> on_feature;
+    // error handler
+    boost::phoenix::function<ErrorHandler> const error_handler;
 };
 
-template <typename Iterator, typename FeatureType, typename FeatureCallback = 
default_feature_callback>
+template <typename Iterator, typename FeatureType, typename FeatureCallback = 
default_feature_callback, typename ErrorHandler = error_handler<Iterator> >
 struct feature_grammar_callback :
         qi::grammar<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback &), space_type>
 {
@@ -89,14 +88,13 @@ struct feature_grammar_callback :
     geometry_grammar<Iterator> geometry_g;
     // rules
     qi::rule<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback&), space_type> start; // START
-    //qi::rule<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback&), space_type> feature_collection;
-    //qi::rule<Iterator, space_type> type;
-    //qi::rule<Iterator, void(context_ptr const&, std::size_t&, 
FeatureCallback&), space_type> features;
     qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& 
ctx, std::size_t, FeatureCallback&), space_type> feature;
     qi::rule<Iterator, qi::locals<feature_ptr,int>, void(context_ptr const& 
ctx, std::size_t, FeatureCallback&), space_type> feature_from_geometry;
     // phoenix functions
     phoenix::function<json::set_geometry_impl> set_geometry;
     phoenix::function<apply_feature_callback> on_feature;
+    // error handler
+    boost::phoenix::function<ErrorHandler> const error_handler;
 };
 
 
diff --git a/include/mapnik/json/feature_collection_grammar_impl.hpp 
b/include/mapnik/json/feature_collection_grammar_impl.hpp
index d4a07e3..49ee249 100644
--- a/include/mapnik/json/feature_collection_grammar_impl.hpp
+++ b/include/mapnik/json/feature_collection_grammar_impl.hpp
@@ -31,14 +31,14 @@
 
 namespace mapnik { namespace json {
 
-template <typename Iterator, typename FeatureType, typename FeatureCallback>
-feature_collection_grammar<Iterator,FeatureType, 
FeatureCallback>::feature_collection_grammar(mapnik::transcoder const& tr)
+template <typename Iterator, typename FeatureType, typename FeatureCallback, 
typename ErrorHandler>
+feature_collection_grammar<Iterator,FeatureType, 
FeatureCallback,ErrorHandler>::feature_collection_grammar(mapnik::transcoder 
const& tr)
         : feature_collection_grammar::base_type(start,"start"),
           feature_g(tr)
 {
         qi::lit_type lit;
         qi::eps_type eps;
-        //qi::_1_type _1;
+        qi::_1_type _1;
         qi::_2_type _2;
         qi::_3_type _3;
         qi::_4_type _4;
@@ -49,8 +49,9 @@ feature_collection_grammar<Iterator,FeatureType, 
FeatureCallback>::feature_colle
         using phoenix::construct;
         using phoenix::new_;
         using phoenix::val;
-
-        start = /*feature_from_geometry(_r1, _r2, _r3) | feature(_r1, _r2, 
_r3) | */feature_collection(_r1, _r2, _r3)
+        using qi::on_error;
+        using qi::fail;
+        start = feature_collection(_r1, _r2, _r3)
             ;
 
         feature_collection = lit('{') >> (type | features(_r1, _r2, _r3) | 
feature_g.json_.key_value) % lit(',') >> lit('}')
@@ -70,37 +71,17 @@ feature_collection_grammar<Iterator,FeatureType, 
FeatureCallback>::feature_colle
             >> feature_g(*_a)[on_feature(_r3,_a)]
             ;
 
-        //feature_from_geometry =
-        //    eps[_a = 
phoenix::construct<mapnik::feature_ptr>(new_<mapnik::feature_impl>(_r1, _r2))]
-        //    >> geometry_g[set_geometry(*_a, _1)] [on_feature(_r3, _a)]
-        //    ;
-
         start.name("start");
         type.name("type");
         features.name("features");
         feature.name("feature");
-        //feature_from_geometry.name("feature-from-geometry");
         feature_g.name("feature-grammar");
-        //geometry_g.name("geometry-grammar");
-
-        qi::on_error<qi::fail>
-            (
-                start
-                , std::clog
-                << phoenix::val("Error parsing GeoJSON ")
-                << _4
-                << phoenix::val(" here: \"")
-                << construct<std::string>(_3, _2)
-                << phoenix::val('\"')
-                << std::endl
-                );
+        on_error<fail>(feature_collection, error_handler(_1, _2, _3, _4));
 }
 
-//
 
-
-template <typename Iterator, typename FeatureType, typename FeatureCallback>
-feature_grammar_callback<Iterator,FeatureType, 
FeatureCallback>::feature_grammar_callback(mapnik::transcoder const& tr)
+template <typename Iterator, typename FeatureType, typename FeatureCallback, 
typename ErrorHandler>
+feature_grammar_callback<Iterator,FeatureType, 
FeatureCallback,ErrorHandler>::feature_grammar_callback(mapnik::transcoder 
const& tr)
     : feature_grammar_callback::base_type(start,"start"),
       feature_g(tr)
 {
@@ -117,7 +98,8 @@ feature_grammar_callback<Iterator,FeatureType, 
FeatureCallback>::feature_grammar
         using phoenix::construct;
         using phoenix::new_;
         using phoenix::val;
-
+        using qi::on_error;
+        using qi::fail;
         start = feature_from_geometry(_r1, _r2, _r3) | feature(_r1, _r2, _r3)
             ;
 
@@ -135,18 +117,7 @@ feature_grammar_callback<Iterator,FeatureType, 
FeatureCallback>::feature_grammar
         feature_from_geometry.name("feature-from-geometry");
         feature_g.name("feature-grammar");
         geometry_g.name("geometry-grammar");
-
-        qi::on_error<qi::fail>
-            (
-                start
-                , std::clog
-                << phoenix::val("Error parsing GeoJSON ")
-                << _4
-                << phoenix::val(" here: \"")
-                << construct<std::string>(_3, _2)
-                << phoenix::val('\"')
-                << std::endl
-                );
+        on_error<fail>(feature, error_handler(_1, _2, _3, _4));
 }
 
 }}
diff --git a/include/mapnik/json/geometry_grammar.hpp 
b/include/mapnik/json/geometry_grammar.hpp
index 4bc25c9..2138777 100644
--- a/include/mapnik/json/geometry_grammar.hpp
+++ b/include/mapnik/json/geometry_grammar.hpp
@@ -45,8 +45,8 @@ struct geometry_grammar :
     geometry_grammar();
     qi::rule<Iterator, mapnik::geometry::geometry<double>(), space_type> start;
     qi::rule<Iterator, qi::locals<int, mapnik::json::coordinates>, 
mapnik::geometry::geometry<double>(), space_type> geometry;
-    qi::symbols<char, int> geometry_type_dispatch;
     qi::rule<Iterator, mapnik::geometry::geometry_collection<double>(), 
space_type> geometry_collection;
+    qi::symbols<char, int> geometry_type_dispatch;
     positions_grammar<Iterator> coordinates;
     boost::phoenix::function<create_geometry_impl> create_geometry;
     // error handler
diff --git a/include/mapnik/json/geometry_grammar_impl.hpp 
b/include/mapnik/json/geometry_grammar_impl.hpp
index 9fa7df9..7cef865 100644
--- a/include/mapnik/json/geometry_grammar_impl.hpp
+++ b/include/mapnik/json/geometry_grammar_impl.hpp
@@ -21,6 +21,7 @@
  *****************************************************************************/
 
 // mapnik
+#include <mapnik/config.hpp>
 #include <mapnik/json/error_handler.hpp>
 #include <mapnik/json/geometry_grammar.hpp>
 #include <mapnik/json/positions_grammar_impl.hpp>
@@ -38,7 +39,6 @@ template <typename Iterator, typename ErrorHandler >
 geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
     : geometry_grammar::base_type(start,"geometry")
 {
-
     qi::lit_type lit;
     qi::int_type int_;
     qi::double_type double_;
@@ -53,25 +53,21 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
     using qi::fail;
     using qi::on_error;
     using phoenix::push_back;
-    start = geometry  | geometry_collection;
+
+    start = geometry.alias(); // | geometry_collection;
 
     geometry = (lit('{')[_a = 0 ]
-                >> (-lit(',') >> lit("\"type\"") >> lit(':') >> 
geometry_type_dispatch[_a = _1]
+                >> (-lit(',') >> (lit("\"type\"") >> lit(':') >> 
geometry_type_dispatch[_a = _1])
+                    ^
+                    (-lit(',') >> (lit("\"coordinates\"") > lit(':') > 
coordinates[_b = _1]))
                     ^
-                    (-lit(',') >> lit("\"coordinates\"") >> lit(':') >> 
coordinates[_b = _1]))[create_geometry(_val,_a,_b)]
+                    (-lit(',') >> lit("\"geometries\"") >> lit(':') >> 
lit('[') >> geometry_collection[_val = _1] >> 
lit(']')))[create_geometry(_val,_a,_b)]
                 >> lit('}'))
         | lit("null")
         ;
 
-    geometry_collection = (lit('{')
-                           >> (-lit(',') >> lit("\"type\"") >> lit(':') >> 
lit("\"GeometryCollection\"")
-                               ^
-                               -lit(',') >> lit("\"geometries\"") >> lit(':')
-                               >> lit('[') >> geometry[push_back(_val, _1)] % 
lit(',') >> lit(']'))
-                           >> lit('}'))
-        | lit("null")
+    geometry_collection = geometry[push_back(_val, _1)] % lit(',')
         ;
-
     geometry_type_dispatch.add
         ("\"Point\"",1)
         ("\"LineString\"",2)
@@ -79,12 +75,13 @@ geometry_grammar<Iterator, ErrorHandler>::geometry_grammar()
         ("\"MultiPoint\"",4)
         ("\"MultiLineString\"",5)
         ("\"MultiPolygon\"",6)
+        ("\"GeometryCollection\"",7)
         ;
 
     // give some rules names
     geometry.name("Geometry");
     geometry_collection.name("GeometryCollection");
-    geometry_type_dispatch.name("type");
+    geometry_type_dispatch.name("type: 
(Point|LineString|Polygon|MultiPoint|MultiLineString|MultiPolygon|GeometryCollection)");
     coordinates.name("coordinates");
     // error handler
     on_error<fail>(start, error_handler(_1, _2, _3, _4));
diff --git a/include/mapnik/util/variant.hpp b/include/mapnik/util/variant.hpp
index 1000887..65eb34f 100644
--- a/include/mapnik/util/variant.hpp
+++ b/include/mapnik/util/variant.hpp
@@ -116,6 +116,21 @@ struct value_traits
         (direct_index == invalid_value) ? convertible_type<T, Types...>::index 
: direct_index;
 };
 
+// check if T is in Types...
+template <typename T, typename...Types>
+struct has_type;
+
+template <typename T, typename First, typename... Types>
+struct has_type<T, First, Types...>
+{
+    static constexpr bool value = std::is_same<T, First>::value
+        || has_type<T, Types...>::value;
+};
+
+template <typename T>
+struct has_type<T> : std::false_type {};
+//
+
 template <typename T, typename...Types>
 struct is_valid_type;
 
@@ -240,6 +255,19 @@ struct variant_helper<T, Types...>
             variant_helper<Types...>::copy(old_id, old_value, new_value);
         }
     }
+    VARIANT_INLINE static void direct_swap(const std::size_t id, void * lhs, 
void * rhs)
+    {
+        using std::swap; //enable ADL
+        if (id == sizeof...(Types))
+        {
+            // both lhs and rhs hold T
+            swap(*reinterpret_cast<T*>(lhs), *reinterpret_cast<T*>(rhs));
+        }
+        else
+        {
+            variant_helper<Types...>::direct_swap(id, lhs, rhs);
+        }
+    }
 };
 
 template<> struct variant_helper<>
@@ -247,6 +275,7 @@ template<> struct variant_helper<>
     VARIANT_INLINE static void destroy(const std::size_t, void *) {}
     VARIANT_INLINE static void move(const std::size_t, void *, void *) {}
     VARIANT_INLINE static void copy(const std::size_t, const void *, void *) {}
+    VARIANT_INLINE static void direct_swap(const std::size_t, void *, void *) 
{}
 };
 
 namespace detail {
@@ -274,7 +303,7 @@ struct unwrapper<recursive_wrapper<T>>
     {
         return obj.get();
     }
-    
+
     auto operator() (recursive_wrapper<T> & obj) const
         -> typename recursive_wrapper<T>::type &
     {
@@ -595,16 +624,33 @@ public:
         helper_type::move(old.type_index, &old.data, &data);
     }
 
-    friend void swap(variant<Types...> & first, variant<Types...> & second)
+private:
+    VARIANT_INLINE void copy_assign(variant<Types...> const& rhs)
     {
-        using std::swap; //enable ADL
-        swap(first.type_index, second.type_index);
-        swap(first.data, second.data);
+        helper_type::destroy(type_index, &data);
+        type_index = detail::invalid_value;
+        helper_type::copy(rhs.type_index, &rhs.data, &data);
+        type_index = rhs.type_index;
+    }
+
+    VARIANT_INLINE void move_assign(variant<Types...> && rhs)
+    {
+        helper_type::destroy(type_index, &data);
+        type_index = detail::invalid_value;
+        helper_type::move(rhs.type_index, &rhs.data, &data);
+        type_index = rhs.type_index;
+    }
+
+public:
+    VARIANT_INLINE variant<Types...>& operator=(variant<Types...> && other)
+    {
+        move_assign(std::move(other));
+        return *this;
     }
 
-    VARIANT_INLINE variant<Types...>& operator=(variant<Types...> other)
+    VARIANT_INLINE variant<Types...>& operator=(variant<Types...> const& other)
     {
-        swap(*this, other);
+        copy_assign(other);
         return *this;
     }
 
@@ -614,7 +660,7 @@ public:
     VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
     {
         variant<Types...> temp(std::forward<T>(rhs));
-        swap(*this, temp);
+        move_assign(std::move(temp));
         return *this;
     }
 
@@ -623,13 +669,14 @@ public:
     VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
     {
         variant<Types...> temp(rhs);
-        swap(*this, temp);
+        copy_assign(temp);
         return *this;
     }
 
     template<typename T>
     VARIANT_INLINE bool is() const
     {
+        static_assert(detail::has_type<T, Types...>::value, "invalid type in T 
in `is<T>()` for this variant");
         return (type_index == detail::direct_type<T, Types...>::index);
     }
 
diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp
index 1041d94..995916b 100644
--- a/include/mapnik/value.hpp
+++ b/include/mapnik/value.hpp
@@ -100,7 +100,7 @@ struct equals
 
     bool operator() (value_double lhs, value_bool rhs) const
     {
-        return static_cast<value_double>(lhs) == rhs;
+        return lhs == static_cast<value_double>(rhs);
     }
 
     bool operator() (value_unicode_string const& lhs,
@@ -123,7 +123,6 @@ struct equals
 };
 
 struct not_equals
-
 {
     template <typename T, typename U>
     bool operator() (const T &, const U &) const
@@ -137,24 +136,24 @@ struct not_equals
         return lhs != rhs;
     }
 
-    bool operator() (value_integer lhs, value_double rhs) const
+    bool operator() (value_bool lhs, value_double rhs) const
     {
         return static_cast<value_double>(lhs) != rhs;
     }
 
-    bool operator() (value_bool lhs, value_double rhs) const
+    bool operator() (value_bool lhs, value_integer rhs) const
     {
-        return static_cast<value_double>(lhs) != rhs;
+        return static_cast<value_integer>(lhs) != rhs;
     }
 
-    bool operator() (value_double lhs, value_integer rhs) const
+    bool operator() (value_integer lhs, value_double rhs) const
     {
-        return  lhs != static_cast<value_double>(rhs);
+        return static_cast<value_double>(lhs) != rhs;
     }
 
-    bool operator() (value_bool lhs, value_integer rhs) const
+    bool operator() (value_double lhs, value_integer rhs) const
     {
-        return static_cast<value_integer>(lhs) != rhs;
+        return  lhs != static_cast<value_double>(rhs);
     }
 
     bool operator() (value_integer lhs, value_bool rhs) const
@@ -185,7 +184,6 @@ struct not_equals
 };
 
 struct greater_than
-
 {
     template <typename T, typename U>
     bool operator()(const T &, const U &) const
@@ -199,14 +197,34 @@ struct greater_than
         return lhs > rhs;
     }
 
+    bool operator() (value_bool lhs, value_double rhs) const
+    {
+        return static_cast<value_double>(lhs) > rhs;
+    }
+
+    bool operator() (value_double lhs, value_bool rhs) const
+    {
+        return lhs > static_cast<value_double>(rhs);
+    }
+
+    bool operator() (value_bool lhs, value_integer rhs) const
+    {
+        return static_cast<value_integer>(lhs) > rhs;
+    }
+
+    bool operator() (value_integer lhs, value_bool rhs) const
+    {
+        return lhs > static_cast<value_integer>(rhs);
+    }
+
     bool operator() (value_integer lhs, value_double rhs) const
     {
-        return  lhs > rhs;
+        return static_cast<value_double>(lhs) > rhs;
     }
 
     bool operator() (value_double lhs, value_integer rhs) const
     {
-        return  lhs > rhs;
+        return static_cast<value_double>(lhs) > rhs;
     }
 
     bool operator() (value_unicode_string const& lhs, value_unicode_string 
const& rhs) const
@@ -221,7 +239,6 @@ struct greater_than
 };
 
 struct greater_or_equal
-
 {
     template <typename T, typename U>
     bool operator()(const T &, const U &) const
@@ -235,14 +252,34 @@ struct greater_or_equal
         return lhs >= rhs;
     }
 
+    bool operator() (value_bool lhs, value_double rhs) const
+    {
+        return static_cast<value_double>(lhs) >= rhs;
+    }
+
+    bool operator() (value_double lhs, value_bool rhs) const
+    {
+        return lhs >= static_cast<value_double>(rhs);
+    }
+
+    bool operator() (value_bool lhs, value_integer rhs) const
+    {
+        return static_cast<value_integer>(lhs) >= rhs;
+    }
+
+    bool operator() (value_integer lhs, value_bool rhs) const
+    {
+        return lhs >= static_cast<value_integer>(rhs);
+    }
+
     bool operator() (value_integer lhs, value_double rhs) const
     {
-        return  lhs >= rhs;
+        return  static_cast<value_double>(lhs) >= rhs;
     }
 
     bool operator() (value_double lhs, value_integer rhs) const
     {
-        return  lhs >= rhs;
+        return  lhs >= static_cast<value_double>(rhs);
     }
 
     bool operator() (value_unicode_string const& lhs, value_unicode_string 
const& rhs) const
@@ -257,7 +294,6 @@ struct greater_or_equal
 };
 
 struct less_than
-
 {
     template <typename T, typename U>
     bool operator()(const T &, const U &) const
@@ -271,14 +307,34 @@ struct less_than
         return lhs < rhs;
     }
 
+    bool operator() (value_bool lhs, value_double rhs) const
+    {
+        return static_cast<value_double>(lhs) < rhs;
+    }
+
+    bool operator() (value_double lhs, value_bool rhs) const
+    {
+        return lhs < static_cast<value_double>(rhs);
+    }
+
+    bool operator() (value_bool lhs, value_integer rhs) const
+    {
+        return static_cast<value_integer>(lhs) < rhs;
+    }
+
+    bool operator() (value_integer lhs, value_bool rhs) const
+    {
+        return lhs < static_cast<value_integer>(rhs);
+    }
+
     bool operator() (value_integer lhs, value_double rhs) const
     {
-        return  lhs < rhs;
+        return  static_cast<value_double>(lhs) < rhs;
     }
 
     bool operator() (value_double lhs, value_integer rhs) const
     {
-        return  lhs < rhs;
+        return  lhs < static_cast<value_double>(rhs);
     }
 
     bool operator()(value_unicode_string const& lhs,
@@ -294,7 +350,6 @@ struct less_than
 };
 
 struct less_or_equal
-
 {
     template <typename T, typename U>
     bool operator()(const T &, const U &) const
@@ -308,14 +363,34 @@ struct less_or_equal
         return lhs <= rhs;
     }
 
+    bool operator() (value_bool lhs, value_double rhs) const
+    {
+        return static_cast<value_double>(lhs) <= rhs;
+    }
+
+    bool operator() (value_double lhs, value_bool rhs) const
+    {
+        return lhs <= static_cast<value_double>(rhs);
+    }
+
+    bool operator() (value_bool lhs, value_integer rhs) const
+    {
+        return static_cast<value_integer>(lhs) <= rhs;
+    }
+
+    bool operator() (value_integer lhs, value_bool rhs) const
+    {
+        return lhs <= static_cast<value_integer>(rhs);
+    }
+
     bool operator() (value_integer lhs, value_double rhs) const
     {
-        return  lhs <= rhs;
+        return static_cast<value_double>(lhs) <= rhs;
     }
 
     bool operator() (value_double lhs, value_integer rhs) const
     {
-        return  lhs <= rhs;
+        return lhs <= static_cast<value_double>(rhs);
     }
 
     bool operator()(value_unicode_string const& lhs,
@@ -917,25 +992,21 @@ inline const value operator+(value const& p1,value const& 
p2)
 
 inline const value operator-(value const& p1,value const& p2)
 {
-
     return value(util::apply_visitor(impl::sub<value>(),p1, p2));
 }
 
 inline const value operator*(value const& p1,value const& p2)
 {
-
     return value(util::apply_visitor(impl::mult<value>(),p1, p2));
 }
 
 inline const value operator/(value const& p1,value const& p2)
 {
-
     return value(util::apply_visitor(impl::div<value>(),p1, p2));
 }
 
 inline const value operator%(value const& p1,value const& p2)
 {
-
     return value(util::apply_visitor(impl::mod<value>(),p1, p2));
 }
 
diff --git a/plugins/input/csv/csv_datasource.cpp 
b/plugins/input/csv/csv_datasource.cpp
index 9aa4ff6..0a8acb8 100644
--- a/plugins/input/csv/csv_datasource.cpp
+++ b/plugins/input/csv/csv_datasource.cpp
@@ -352,7 +352,6 @@ void csv_datasource::parse_csv(T & stream)
                 }
                 if (++feature_count != 1) continue;
                 auto beg = values.begin();
-                auto end = values.end();
                 for (std::size_t i = 0; i < num_headers; ++i)
                 {
                     std::string const& header = headers_.at(i);
diff --git a/plugins/input/geojson/geojson_datasource.cpp 
b/plugins/input/geojson/geojson_datasource.cpp
index afeb84d..28648c0 100644
--- a/plugins/input/geojson/geojson_datasource.cpp
+++ b/plugins/input/geojson/geojson_datasource.cpp
@@ -271,12 +271,12 @@ void geojson_datasource::initialise_index(Iterator start, 
Iterator end)
         std::size_t start_id = 1;
         mapnik::json::default_feature_callback callback(features_);
         bool result = boost::spirit::qi::phrase_parse(itr, end, 
(geojson_datasource_static_feature_callback_grammar)
-                                                 
(boost::phoenix::ref(ctx),boost::phoenix::ref(start_id), 
boost::phoenix::ref(callback)),
+                                                 (boost::phoenix::ref(ctx), 
boost::phoenix::ref(start_id), boost::phoenix::ref(callback)),
                                                  space);
         if (!result || itr != end)
         {
-            if (!inline_string_.empty()) throw 
mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file 
from in-memory string");
-            else throw mapnik::datasource_exception("geojson_datasource: 
Failed parse GeoJSON file '" + filename_ + "'");
+            if (!inline_string_.empty()) throw 
mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file 
from in-memory string");
+            else throw mapnik::datasource_exception("geojson_datasource: 
Failed to parse GeoJSON file '" + filename_ + "'");
         }
 
         using values_container = std::vector< std::pair<box_type, 
std::pair<std::size_t, std::size_t>>>;
@@ -363,8 +363,8 @@ void geojson_datasource::parse_geojson(Iterator start, 
Iterator end)
                                                   space);
     if (!result || itr != end)
     {
-        if (!inline_string_.empty()) throw 
mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file 
from in-memory string");
-        else throw mapnik::datasource_exception("geojson_datasource: Failed 
parse GeoJSON file '" + filename_ + "'");
+        if (!inline_string_.empty()) throw 
mapnik::datasource_exception("geojson_datasource: Failed to parse GeoJSON file 
from in-memory string");
+        else throw mapnik::datasource_exception("geojson_datasource: Failed to 
parse GeoJSON file '" + filename_ + "'");
     }
 
     if (features_.size() == 0)
diff --git a/plugins/input/geojson/geojson_index_featureset.cpp 
b/plugins/input/geojson/geojson_index_featureset.cpp
index 2856916..bdf7f8a 100644
--- a/plugins/input/geojson/geojson_index_featureset.cpp
+++ b/plugins/input/geojson/geojson_index_featureset.cpp
@@ -28,6 +28,7 @@
 #include <mapnik/json/feature_grammar.hpp>
 #include <mapnik/util/utf_conv_win.hpp>
 #include <mapnik/util/spatial_index.hpp>
+#include <mapnik/geometry_is_empty.hpp>
 // stl
 #include <string>
 #include <vector>
@@ -96,8 +97,11 @@ mapnik::feature_ptr geojson_index_featureset::next()
         mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx_, 
feature_id_++));
         if (!qi::phrase_parse(start, end, 
(grammar)(boost::phoenix::ref(*feature)), space) || start != end)
         {
-            throw std::runtime_error("Failed to parse geojson feature");
+            throw std::runtime_error("Failed to parse GeoJSON feature");
         }
+        // skip empty geometries
+        if (mapnik::geometry::is_empty(feature->get_geometry()))
+            continue;
         return feature;
     }
     return mapnik::feature_ptr();
diff --git a/plugins/input/geojson/geojson_memory_index_featureset.cpp 
b/plugins/input/geojson/geojson_memory_index_featureset.cpp
index 99a79ff..61c5053 100644
--- a/plugins/input/geojson/geojson_memory_index_featureset.cpp
+++ b/plugins/input/geojson/geojson_memory_index_featureset.cpp
@@ -26,6 +26,7 @@
 #include <mapnik/json/geometry_grammar.hpp>
 #include <mapnik/json/feature_grammar.hpp>
 #include <mapnik/util/utf_conv_win.hpp>
+#include <mapnik/geometry_is_empty.hpp>
 // stl
 #include <string>
 #include <vector>
@@ -52,7 +53,7 @@ 
geojson_memory_index_featureset::~geojson_memory_index_featureset() {}
 
 mapnik::feature_ptr geojson_memory_index_featureset::next()
 {
-    if (index_itr_ != index_end_)
+    while (index_itr_ != index_end_)
     {
         geojson_datasource::item_type const& item = *index_itr_++;
         std::size_t file_offset = item.second.first;
@@ -61,7 +62,6 @@ mapnik::feature_ptr geojson_memory_index_featureset::next()
         std::vector<char> json;
         json.resize(size);
         std::fread(json.data(), size, 1, file_.get());
-
         using chr_iterator_type = char const*;
         chr_iterator_type start = json.data();
         chr_iterator_type end = start + json.size();
@@ -74,6 +74,9 @@ mapnik::feature_ptr geojson_memory_index_featureset::next()
         {
             throw std::runtime_error("Failed to parse geojson feature");
         }
+        // skip empty geometries
+        if (mapnik::geometry::is_empty(feature->get_geometry()))
+            continue;
         return feature;
     }
     return mapnik::feature_ptr();
diff --git a/src/image.cpp b/src/image.cpp
index 32c8433..5141860 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -59,10 +59,11 @@ buffer::buffer(buffer && rhs) noexcept
 // copy
 buffer::buffer(buffer const& rhs)
     : size_(rhs.size_),
-      data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : 
nullptr)),
-      owns_(true)
+      data_(static_cast<unsigned char*>((rhs.owns_ && size_ != 0) ? ::operator 
new(size_) : nullptr)),
+      owns_(rhs.owns_)
 {
     if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_);
+    else data_ = rhs.data_;
 }
 
 buffer::~buffer()
diff --git a/test/unit/core/box2d_test.cpp b/test/unit/core/box2d_test.cpp
index 0ed32f8..87f2e14 100644
--- a/test/unit/core/box2d_test.cpp
+++ b/test/unit/core/box2d_test.cpp
@@ -1,6 +1,5 @@
 #include "catch.hpp"
 
-#include <iostream>
 #include <mapnik/coord.hpp>
 #include <mapnik/box2d.hpp>
 
diff --git a/test/unit/core/comparison_test.cpp 
b/test/unit/core/comparison_test.cpp
index 2cfbc08..41b524c 100644
--- a/test/unit/core/comparison_test.cpp
+++ b/test/unit/core/comparison_test.cpp
@@ -2,7 +2,6 @@
 
 #include <mapnik/value_types.hpp>
 #include <mapnik/value.hpp>
-#include <mapnik/unicode.hpp>
 
 TEST_CASE("comparison")
 {
@@ -12,6 +11,10 @@ TEST_CASE("comparison")
         mapnik::value v1 = 1.001; // mapnik::value_double
         mapnik::value v2 = true; // mapnik::value_boolean
 
+        CHECK(v0.is<mapnik::value_integer>());
+        CHECK(v1.is<mapnik::value_double>());
+        CHECK(v2.is<mapnik::value_bool>());
+
         REQUIRE(!(v0 == v1));
         REQUIRE(!(v1 == v0));
 
@@ -29,6 +32,11 @@ TEST_CASE("comparison")
         mapnik::value v2 = true; // mapnik::value_boolean
         mapnik::value v3 = mapnik::value_null(); //
 
+        CHECK(v0.is<mapnik::value_integer>());
+        CHECK(v1.is<mapnik::value_double>());
+        CHECK(v2.is<mapnik::value_bool>());
+        CHECK(v3.is<mapnik::value_null>());
+
         REQUIRE(v0 != v1);
         REQUIRE(v1 != v0);
 
@@ -46,4 +54,63 @@ TEST_CASE("comparison")
         REQUIRE(v2 != v3);
 
     }
+    SECTION("operator<,<=,>,>=")
+    {
+        mapnik::value v0 = 1;
+        mapnik::value v1 = 1.01;
+        mapnik::value v2 = true;
+        mapnik::value v3 = 2;
+
+        CHECK(v0.is<mapnik::value_integer>());
+        CHECK(v1.is<mapnik::value_double>());
+        CHECK(v2.is<mapnik::value_bool>());
+        CHECK(v3.is<mapnik::value_integer>());
+        // value_integer | value_double
+        // 1 < 1.01 => true
+        // 1.01 > 1 => true
+        REQUIRE(v0 < v1);
+        REQUIRE(v1 > v0);
+        // 1 <= 1.01 => true
+        // 1.01 >= 1 => true
+        REQUIRE(v0 <= v1);
+        REQUIRE(v1 >= v0);
+
+        // value_bool | value_integer
+        // true < 1 => false
+        // true > 1 => false
+        REQUIRE(!(v2 < v0));
+        REQUIRE(!(v2 > v0));
+        // true <= 1 => true
+        // true >= 1 => true
+        REQUIRE(v2 <= v0);
+        REQUIRE(v2 >= v0);
+        // 1 > true => false
+        // 1 < true => false
+        REQUIRE(!(v0 > v2));
+        REQUIRE(!(v0 < v2));
+        // 1 >= true => true
+        // 1 <= true => true
+        REQUIRE(v0 >= v2);
+        REQUIRE(v0 <= v2);
+
+        // value_bool | value_doble
+        // true < 1.01 => true
+        // 1.01 > true => true
+        REQUIRE(v2 < v1);
+        REQUIRE(v1 > v2);
+        // true <= 1.01 => true
+        // 1.01 >= true => true
+        REQUIRE(v2 <= v1);
+        REQUIRE(v1 >= v2);
+
+        // value_integer | value_integer
+        // 1 < 2 => true
+        // 2 > 1 => true
+        REQUIRE(v0 < v3);
+        REQUIRE(v3 > v0);
+        // 1 <= 2 => true
+        // 2 >= 1 => true
+        REQUIRE(v0 <= v3);
+        REQUIRE(v3 >= v0);
+    }
 }
diff --git a/test/unit/core/conversions_test.cpp 
b/test/unit/core/conversions_test.cpp
index 0b42d85..ba0c223 100644
--- a/test/unit/core/conversions_test.cpp
+++ b/test/unit/core/conversions_test.cpp
@@ -6,8 +6,6 @@
 #include <mapnik/util/conversions.hpp>
 
 #include <iostream>
-#include <vector>
-#include <algorithm>
 #include <unordered_map>
 #include <sstream>
 
diff --git a/test/unit/core/copy_move_test.cpp 
b/test/unit/core/copy_move_test.cpp
index a219178..c4c48cf 100644
--- a/test/unit/core/copy_move_test.cpp
+++ b/test/unit/core/copy_move_test.cpp
@@ -6,9 +6,6 @@
 #include <mapnik/datasource_cache.hpp>
 #include <mapnik/util/fs.hpp>
 
-#include <vector>
-#include <algorithm>
-
 #include "catch.hpp"
 
 
diff --git a/test/unit/core/params_test.cpp b/test/unit/core/params_test.cpp
index 879b861..677de7a 100644
--- a/test/unit/core/params_test.cpp
+++ b/test/unit/core/params_test.cpp
@@ -4,8 +4,6 @@
 #include <mapnik/value_types.hpp>
 #include <mapnik/params.hpp>
 #include <mapnik/boolean.hpp>
-#include <vector>
-#include <algorithm>
 
 #include <ostream>
 
diff --git a/test/unit/datasource/csv.cpp b/test/unit/datasource/csv.cpp
index eee9b91..75da910 100644
--- a/test/unit/datasource/csv.cpp
+++ b/test/unit/datasource/csv.cpp
@@ -21,6 +21,7 @@
  *****************************************************************************/
 
 #include "catch.hpp"
+#include "ds_test_util.hpp"
 
 #include <mapnik/map.hpp>
 #include <mapnik/datasource.hpp>
@@ -32,23 +33,32 @@
 #include <mapnik/expression_evaluator.hpp>
 #include <mapnik/debug.hpp>
 #include <mapnik/util/fs.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/range/iterator_range_core.hpp>
 #include <boost/format.hpp>
 #include <boost/optional/optional_io.hpp>
 
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-local-typedef"
+#include <boost/algorithm/string.hpp>
+#pragma GCC diagnostic pop
+
 #include <iostream>
 
-namespace bfs = boost::filesystem;
 
 namespace {
-void add_csv_files(bfs::path dir, std::vector<bfs::path> &csv_files)
+
+bool is_csv(std::string const& filename)
 {
-    for (auto const &entry : boost::make_iterator_range(
-             bfs::directory_iterator(dir), bfs::directory_iterator()))
+    return boost::iends_with(filename,".csv")
+        || boost::iends_with(filename,".tsv");
+}
+
+void add_csv_files(std::string dir, std::vector<std::string> &csv_files)
+{
+    for (auto const& path : mapnik::util::list_directory(dir))
     {
-        auto path = entry.path();
-        if (path.extension().native() == ".csv")
+        if (is_csv(path))
         {
             csv_files.emplace_back(path);
         }
@@ -67,122 +77,6 @@ mapnik::datasource_ptr get_csv_ds(std::string const 
&file_name, bool strict = tr
     return ds;
 }
 
-void require_field_names(std::vector<mapnik::attribute_descriptor> const 
&fields,
-                         std::initializer_list<std::string> const &names)
-{
-    REQUIRE(fields.size() == names.size());
-    auto itr_a = fields.begin();
-    auto const end_a = fields.end();
-    auto itr_b = names.begin();
-    for (; itr_a != end_a; ++itr_a, ++itr_b)
-    {
-        CHECK(itr_a->get_name() == *itr_b);
-    }
-}
-
-void require_field_types(std::vector<mapnik::attribute_descriptor> const 
&fields,
-                         std::initializer_list<mapnik::eAttributeType> const 
&types) {
-    REQUIRE(fields.size() == types.size());
-    auto itr_a = fields.begin();
-    auto const end_a = fields.end();
-    auto itr_b = types.begin();
-    for (; itr_a != end_a; ++itr_a, ++itr_b) {
-        CHECK(itr_a->get_type() == *itr_b);
-    }
-}
-
-mapnik::featureset_ptr all_features(mapnik::datasource_ptr ds) {
-    auto fields = ds->get_descriptor().get_descriptors();
-    mapnik::query query(ds->envelope());
-    for (auto const &field : fields) {
-        query.add_property_name(field.get_name());
-    }
-    return ds->features(query);
-}
-
-std::size_t count_features(mapnik::featureset_ptr features) {
-    std::size_t count = 0;
-    while (features->next()) {
-        ++count;
-    }
-    return count;
-}
-
-using attr = std::tuple<std::string, mapnik::value>;
-void require_attributes(mapnik::feature_ptr feature,
-                        std::initializer_list<attr> const &attrs) {
-    REQUIRE(bool(feature));
-    for (auto const &kv : attrs) {
-        REQUIRE(feature->has_key(std::get<0>(kv)));
-        CHECK(feature->get(std::get<0>(kv)) == std::get<1>(kv));
-    }
-}
-
-namespace detail {
-struct feature_count {
-    template <typename T>
-    std::size_t operator()(T const &geom) const {
-        return mapnik::util::apply_visitor(*this, geom);
-    }
-
-    std::size_t operator()(mapnik::geometry::geometry_empty const &) const {
-        return 0;
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::point<T> const &) const {
-        return 1;
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::line_string<T> const &) const {
-        return 1;
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::polygon<T> const &) const {
-        return 1;
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::multi_point<T> const &mp) const {
-        return mp.size();
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::multi_line_string<T> const &mls) 
const {
-        return mls.size();
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::multi_polygon<T> const &mp) const 
{
-        return mp.size();
-    }
-
-    template <typename T>
-    std::size_t operator()(mapnik::geometry::geometry_collection<T> const 
&col) const {
-        std::size_t sum = 0;
-        for (auto const &geom : col) {
-            sum += operator()(geom);
-        }
-        return sum;
-    }
-};
-} // namespace detail
-
-template <typename T>
-std::size_t feature_count(mapnik::geometry::geometry<T> const &g) {
-    return detail::feature_count()(g);
-}
-
-void require_geometry(mapnik::feature_ptr feature,
-                      std::size_t num_parts,
-                      mapnik::geometry::geometry_types type) {
-    REQUIRE(bool(feature));
-    CHECK(mapnik::geometry::geometry_type(feature->get_geometry()) == type);
-    CHECK(feature_count(feature->get_geometry()) == num_parts);
-}
-
 int create_disk_index(std::string const& filename, bool silent = true)
 {
     std::string cmd;
@@ -206,14 +100,11 @@ int create_disk_index(std::string const& filename, bool 
silent = true)
 
 static const std::string csv_plugin("./plugins/input/csv.input");
 
-const bool registered = 
mapnik::datasource_cache::instance().register_datasources(csv_plugin);
-
 TEST_CASE("csv") {
 
     if (mapnik::util::exists(csv_plugin))
     {
-        REQUIRE(registered);
-        // make the tests silent since we intentially test error conditions 
that are noisy
+        // make the tests silent since we intentionally test error conditions 
that are noisy
         auto const severity = mapnik::logger::instance().get_severity();
         mapnik::logger::instance().set_severity(mapnik::logger::none);
 
@@ -250,7 +141,7 @@ TEST_CASE("csv") {
             {
                 if (have_csv_plugin)
                 {
-                    std::vector<bfs::path> broken;
+                    std::vector<std::string> broken;
                     add_csv_files("test/data/csv/fails", broken);
                     add_csv_files("test/data/csv/warns", broken);
                     
broken.emplace_back("test/data/csv/fails/does_not_exist.csv");
@@ -260,28 +151,28 @@ TEST_CASE("csv") {
                         bool require_fail = true;
                         if (create_index)
                         {
-                            int ret = create_disk_index(path.native());
+                            int ret = create_disk_index(path);
                             int ret_posix = (ret >> 8) & 0x000000ff;
                             INFO(ret);
                             INFO(ret_posix);
-                            require_fail = (path.native() == 
"test/data/csv/warns/feature_id_counting.csv") ? false : true;
+                            require_fail = (path == 
"test/data/csv/warns/feature_id_counting.csv") ? false : true;
                             if (!require_fail)
                             {
-                                REQUIRE(mapnik::util::exists(path.native() + 
".index"));
+                                REQUIRE(mapnik::util::exists(path + ".index"));
                             }
                         }
                         INFO(path);
                         if (require_fail)
                         {
-                            REQUIRE_THROWS(get_csv_ds(path.native()));
+                            REQUIRE_THROWS(get_csv_ds(path));
                         }
                         else
                         {
-                            CHECK(bool(get_csv_ds(path.native())));
+                            CHECK(bool(get_csv_ds(path)));
                         }
-                        if (mapnik::util::exists(path.native() + ".index"))
+                        if (mapnik::util::exists(path + ".index"))
                         {
-                            CHECK(mapnik::util::remove(path.native() + 
".index"));
+                            CHECK(mapnik::util::remove(path + ".index"));
                         }
                     }
                 }
@@ -292,36 +183,36 @@ TEST_CASE("csv") {
         {
             if (have_csv_plugin)
             {
-                std::vector<bfs::path> good;
+                std::vector<std::string> good;
                 add_csv_files("test/data/csv", good);
                 add_csv_files("test/data/csv/warns", good);
 
                 for (auto const& path : good)
                 {
                     // cleanup in the case of a failed previous run
-                    if (mapnik::util::exists(path.native() + ".index"))
+                    if (mapnik::util::exists(path + ".index"))
                     {
-                        boost::filesystem::remove(path.native() + ".index");
+                        mapnik::util::remove(path + ".index");
                     }
                     for (auto create_index : { false, true })
                     {
                         if (create_index)
                         {
-                            int ret = create_disk_index(path.native());
+                            int ret = create_disk_index(path);
                             int ret_posix = (ret >> 8) & 0x000000ff;
                             INFO(ret);
                             INFO(ret_posix);
-                            if (path.native() != 
"test/data/csv/more_headers_than_column_values.csv") // mapnik-index won't 
create *.index for 0 features
+                            if (path != 
"test/data/csv/more_headers_than_column_values.csv") // mapnik-index won't 
create *.index for 0 features
                             {
-                                CHECK(mapnik::util::exists(path.native() + 
".index"));
+                                CHECK(mapnik::util::exists(path + ".index"));
                             }
                         }
-                        auto ds = get_csv_ds(path.native(), false);
+                        auto ds = get_csv_ds(path, false);
                         // require a non-null pointer returned
                         REQUIRE(bool(ds));
-                        if (mapnik::util::exists(path.native() + ".index"))
+                        if (mapnik::util::exists(path + ".index"))
                         {
-                            CHECK(mapnik::util::remove(path.native() + 
".index"));
+                            CHECK(mapnik::util::remove(path + ".index"));
                         }
                     }
                 }
@@ -338,7 +229,7 @@ TEST_CASE("csv") {
                     // cleanup in the case of a failed previous run
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                     if (create_index)
                     {
@@ -369,7 +260,7 @@ TEST_CASE("csv") {
                         });
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                 }
             }
@@ -383,7 +274,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -413,7 +304,7 @@ TEST_CASE("csv") {
                     });
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -426,7 +317,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -444,7 +335,7 @@ TEST_CASE("csv") {
                 CHECK(count_features(all_features(ds)) == 2);
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -457,7 +348,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -497,7 +388,7 @@ TEST_CASE("csv") {
                 }
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -510,7 +401,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -541,7 +432,7 @@ TEST_CASE("csv") {
                         , attr{"name", mapnik::value_unicode_string("c/c") } 
});
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -554,7 +445,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -581,7 +472,7 @@ TEST_CASE("csv") {
                 require_geometry(featureset->next(), 2, 
geometry_types::MultiPolygon);
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -594,7 +485,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -615,7 +506,7 @@ TEST_CASE("csv") {
                 CHECK(feature->get("_4") == 
mapnik::value_unicode_string("missing"));
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -628,7 +519,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -657,7 +548,7 @@ TEST_CASE("csv") {
                 CHECK(value == true);
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -671,7 +562,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -698,7 +589,7 @@ TEST_CASE("csv") {
                         attr{"x", 2.5}, attr{"y", 2.5}, attr{"label", 
ustring("2.5,2.5") } });
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -713,7 +604,7 @@ TEST_CASE("csv") {
                     // cleanup in the case of a failed previous run
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                     if (create_index)
                     {
@@ -730,7 +621,7 @@ TEST_CASE("csv") {
                             attr{"x", 1}, attr{"y", 10}, attr{"z", 9999.9999} 
});
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                 }
             }
@@ -751,7 +642,7 @@ TEST_CASE("csv") {
                     // cleanup in the case of a failed previous run
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                     if (create_index)
                     {
@@ -769,7 +660,7 @@ TEST_CASE("csv") {
                             , attr{"line", ustring("many\n  lines\n  of text\n 
 with unix newlines")} });
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                 }
             }
@@ -782,7 +673,7 @@ TEST_CASE("csv") {
                 std::string filename = "test/data/csv/tabs_in_csv.csv";
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -799,7 +690,7 @@ TEST_CASE("csv") {
                         attr{"x", -122}, attr{"y", 48}, attr{"z", 0} });
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -817,7 +708,7 @@ TEST_CASE("csv") {
                     // cleanup in the case of a failed previous run
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                     if (create_index)
                     {
@@ -834,7 +725,7 @@ TEST_CASE("csv") {
                             attr{"x", 0}, attr{"y", 0}, attr{"z", 
ustring("hello")} });
                     if (mapnik::util::exists(filename + ".index"))
                     {
-                        boost::filesystem::remove(filename + ".index");
+                        mapnik::util::remove(filename + ".index");
                     }
                 }
             }
@@ -849,7 +740,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -872,7 +763,7 @@ TEST_CASE("csv") {
 
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -885,7 +776,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -910,7 +801,7 @@ TEST_CASE("csv") {
                 REQUIRE_THROWS(ds->features(query));
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
@@ -924,7 +815,7 @@ TEST_CASE("csv") {
                 // cleanup in the case of a failed previous run
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
                 if (create_index)
                 {
@@ -948,7 +839,7 @@ TEST_CASE("csv") {
                         attr{"x", 0}, attr{"y", 0}, attr{"fips", 
ustring("005")}});
                 if (mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         } // END SECTION
diff --git a/test/unit/datasource/ds_test_util.hpp 
b/test/unit/datasource/ds_test_util.hpp
new file mode 100644
index 0000000..e334318
--- /dev/null
+++ b/test/unit/datasource/ds_test_util.hpp
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 Artem Pavlenko
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *****************************************************************************/
+
+#include "catch.hpp"
+
+#include <mapnik/datasource.hpp>
+#include <mapnik/datasource_cache.hpp>
+#include <mapnik/geometry.hpp>
+#include <mapnik/geometry_types.hpp>
+#include <mapnik/geometry_type.hpp>
+
+namespace {
+
+template <typename T>
+std::string vector_to_string(T const& vec)
+{
+    std::stringstream s;
+    for (auto const& item : vec)
+    {
+        s << item << "\n";
+    }
+    return s.str();
+}
+
+template <>
+std::string vector_to_string(std::vector<mapnik::attribute_descriptor> const& 
vec)
+{
+    std::stringstream s;
+    for (auto const& item : vec)
+    {
+        s << item.get_name() << "\n";
+    }
+    return s.str();
+}
+
+inline void require_field_names(std::vector<mapnik::attribute_descriptor> 
const &fields,
+                         std::initializer_list<std::string> const &names)
+{
+    INFO("fields: " + vector_to_string(fields) + " names: " +  
vector_to_string(names));
+    REQUIRE(fields.size() == names.size());
+    auto itr_a = fields.begin();
+    auto const end_a = fields.end();
+    auto itr_b = names.begin();
+    for (; itr_a != end_a; ++itr_a, ++itr_b)
+    {
+        CHECK(itr_a->get_name() == *itr_b);
+    }
+}
+
+inline void require_field_types(std::vector<mapnik::attribute_descriptor> 
const &fields,
+                         std::initializer_list<mapnik::eAttributeType> const 
&types) {
+    REQUIRE(fields.size() == types.size());
+    auto itr_a = fields.begin();
+    auto const end_a = fields.end();
+    auto itr_b = types.begin();
+    for (; itr_a != end_a; ++itr_a, ++itr_b) {
+        CHECK(itr_a->get_type() == *itr_b);
+    }
+}
+
+inline mapnik::featureset_ptr all_features(mapnik::datasource_ptr ds) {
+    auto fields = ds->get_descriptor().get_descriptors();
+    mapnik::query query(ds->envelope());
+    for (auto const &field : fields) {
+        query.add_property_name(field.get_name());
+    }
+    return ds->features(query);
+}
+
+inline std::size_t count_features(mapnik::featureset_ptr features) {
+    std::size_t count = 0;
+    while (features->next()) {
+        ++count;
+    }
+    return count;
+}
+
+using attr = std::tuple<std::string, mapnik::value>;
+inline void require_attributes(mapnik::feature_ptr feature,
+                        std::initializer_list<attr> const &attrs) {
+    REQUIRE(bool(feature));
+    for (auto const &kv : attrs) {
+        REQUIRE(feature->has_key(std::get<0>(kv)));
+        CHECK(feature->get(std::get<0>(kv)) == std::get<1>(kv));
+    }
+}
+
+namespace detail {
+struct feature_count {
+    template <typename T>
+    std::size_t operator()(T const &geom) const {
+        return mapnik::util::apply_visitor(*this, geom);
+    }
+
+    std::size_t operator()(mapnik::geometry::geometry_empty const &) const {
+        return 0;
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::point<T> const &) const {
+        return 1;
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::line_string<T> const &) const {
+        return 1;
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::polygon<T> const &) const {
+        return 1;
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::multi_point<T> const &mp) const {
+        return mp.size();
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::multi_line_string<T> const &mls) 
const {
+        return mls.size();
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::multi_polygon<T> const &mp) const 
{
+        return mp.size();
+    }
+
+    template <typename T>
+    std::size_t operator()(mapnik::geometry::geometry_collection<T> const 
&col) const {
+        std::size_t sum = 0;
+        for (auto const &geom : col) {
+            sum += operator()(geom);
+        }
+        return sum;
+    }
+};
+} // namespace detail
+
+template <typename T>
+inline std::size_t feature_count(mapnik::geometry::geometry<T> const &g) {
+    return detail::feature_count()(g);
+}
+
+inline void require_geometry(mapnik::feature_ptr feature,
+                      std::size_t num_parts,
+                      mapnik::geometry::geometry_types type) {
+    REQUIRE(bool(feature));
+    CHECK(mapnik::geometry::geometry_type(feature->get_geometry()) == type);
+    CHECK(feature_count(feature->get_geometry()) == num_parts);
+}
+
+}
diff --git a/test/unit/datasource/geojson.cpp b/test/unit/datasource/geojson.cpp
index d8e8e2a..cd9edce 100644
--- a/test/unit/datasource/geojson.cpp
+++ b/test/unit/datasource/geojson.cpp
@@ -22,7 +22,6 @@
 
 #include "catch.hpp"
 
-#include <mapnik/map.hpp>
 #include <mapnik/datasource.hpp>
 #include <mapnik/datasource_cache.hpp>
 #include <mapnik/geometry.hpp>
@@ -30,9 +29,17 @@
 #include <mapnik/util/fs.hpp>
 #include <cstdlib>
 
-#include <boost/filesystem/operations.hpp>
 #include <boost/optional/optional_io.hpp>
 
+/*
+
+Compile and run just this test:
+
+clang++ -o test-geojson -g -I./test/ test/unit/run.cpp 
test/unit/datasource/geojson.cpp `mapnik-config --all-flags`
+./test-geojson -d yes
+
+*/
+
 namespace {
 
 std::pair<mapnik::datasource_ptr,mapnik::feature_ptr> 
fetch_first_feature(std::string const& filename, bool cache_features)
@@ -320,7 +327,7 @@ TEST_CASE("geojson") {
             // cleanup in the case of a failed previous run
             if (mapnik::util::exists(filename + ".index"))
             {
-                boost::filesystem::remove(filename + ".index");
+                mapnik::util::remove(filename + ".index");
             }
 
             for (auto create_index : { true, false })
@@ -387,7 +394,7 @@ TEST_CASE("geojson") {
             // cleanup in the case of a failed previous run
             if (mapnik::util::exists(filename + ".index"))
             {
-                boost::filesystem::remove(filename + ".index");
+                mapnik::util::remove(filename + ".index");
             }
 
             for (auto create_index : { true, false })
@@ -423,7 +430,7 @@ TEST_CASE("geojson") {
                 // cleanup
                 if (create_index && mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
 
             }
@@ -439,7 +446,7 @@ TEST_CASE("geojson") {
             // cleanup in the case of a failed previous run
             if (mapnik::util::exists(filename + ".index"))
             {
-                boost::filesystem::remove(filename + ".index");
+                mapnik::util::remove(filename + ".index");
             }
 
             for (auto create_index : { true, false })
@@ -474,7 +481,7 @@ TEST_CASE("geojson") {
                 // cleanup
                 if (create_index && mapnik::util::exists(filename + ".index"))
                 {
-                    boost::filesystem::remove(filename + ".index");
+                    mapnik::util::remove(filename + ".index");
                 }
             }
         }
diff --git a/test/unit/datasource/ogr.cpp b/test/unit/datasource/ogr.cpp
index 3dddb85..5401c1f 100644
--- a/test/unit/datasource/ogr.cpp
+++ b/test/unit/datasource/ogr.cpp
@@ -28,7 +28,6 @@
 #include <mapnik/image.hpp>
 #include <mapnik/image_reader.hpp>
 #include <mapnik/image_util.hpp>
-#include <mapnik/font_engine_freetype.hpp>
 #include <mapnik/util/fs.hpp>
 
 TEST_CASE("ogr") {
diff --git a/test/unit/datasource/postgis.cpp b/test/unit/datasource/postgis.cpp
new file mode 100644
index 0000000..4aaa76f
--- /dev/null
+++ b/test/unit/datasource/postgis.cpp
@@ -0,0 +1,94 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 Artem Pavlenko
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *****************************************************************************/
+
+#include "catch.hpp"
+#include "ds_test_util.hpp"
+
+#include <mapnik/datasource.hpp>
+#include <mapnik/datasource_cache.hpp>
+#include <mapnik/geometry_type.hpp>
+#include <mapnik/util/fs.hpp>
+
+/*
+
+Compile and run just this test:
+
+clang++ -o test-postgis -g -I./test/ test/unit/run.cpp 
test/unit/datasource/postgis.cpp `mapnik-config --all-flags` && ./test-postgis 
-d yes
+
+*/
+
+namespace {
+
+int run(std::string const& command, bool silent = false)
+{
+    std::string cmd;
+    if (std::getenv("DYLD_LIBRARY_PATH") != nullptr)
+    {
+        cmd += std::string("export DYLD_LIBRARY_PATH=") + 
std::getenv("DYLD_LIBRARY_PATH") + " && ";
+    }
+    cmd += command;
+    if (silent)
+    {
+#ifndef _WINDOWS
+        cmd += " 2>/dev/null";
+#else
+        cmd += " 2> nul";
+#endif
+    }
+    bool worked = (std::system(cmd.c_str()) == 0);
+    if (silent == true) return true;
+    return worked;
+}
+
+
+TEST_CASE("postgis") {
+
+    SECTION("Postgis data initialization")
+    {
+        REQUIRE(run("dropdb mapnik-tmp-postgis-test-db",true));
+        REQUIRE(run("createdb -T template_postgis 
mapnik-tmp-postgis-test-db"));
+        std::stringstream cmd;
+        cmd << "psql -q mapnik-tmp-postgis-test-db -f 
./test/data/sql/table1.sql";
+        REQUIRE(run(cmd.str()));
+    }
+
+    std::string datasource_plugin("./plugins/input/postgis.input");
+    if (mapnik::util::exists(datasource_plugin))
+    {
+        SECTION("Postgis plugin initialization")
+        {
+            mapnik::parameters params;
+            params["type"] = "postgis";
+            params["dbname"] = "mapnik-tmp-postgis-test-db";
+            params["table"] = "test";
+            auto ds = mapnik::datasource_cache::instance().create(params);
+            REQUIRE(ds != nullptr);
+            CHECK(ds->type() == mapnik::datasource::datasource_t::Vector);
+            auto fields = ds->get_descriptor().get_descriptors();
+            require_field_names(fields, {"gid"});
+            require_field_types(fields, {mapnik::Integer});
+        }
+    }
+}
+
+
+}
\ No newline at end of file
diff --git a/test/unit/datasource/spatial_index.cpp 
b/test/unit/datasource/spatial_index.cpp
index 62fde03..2eb794b 100644
--- a/test/unit/datasource/spatial_index.cpp
+++ b/test/unit/datasource/spatial_index.cpp
@@ -20,9 +20,6 @@
  *
  *****************************************************************************/
 
-#include <iostream>
-#include <fstream>
-
 #include "catch.hpp"
 
 #include <mapnik/quad_tree.hpp>
diff --git a/test/unit/font/fontset_runtime_test.cpp 
b/test/unit/font/fontset_runtime_test.cpp
index 4e703fa..e5a6211 100644
--- a/test/unit/font/fontset_runtime_test.cpp
+++ b/test/unit/font/fontset_runtime_test.cpp
@@ -1,8 +1,6 @@
 #include "catch.hpp"
 
-#include <iostream>
 #include <mapnik/memory_datasource.hpp>
-#include <mapnik/datasource_cache.hpp>
 #include <mapnik/feature.hpp>
 #include <mapnik/feature_factory.hpp>
 #include <mapnik/unicode.hpp>
@@ -13,16 +11,10 @@
 #include <mapnik/rule.hpp>
 #include <mapnik/feature_type_style.hpp>
 #include <mapnik/agg_renderer.hpp>
-#include <mapnik/image_util.hpp>
-#include <mapnik/color_factory.hpp>
-#include <mapnik/save_map.hpp>
 #include <mapnik/value_types.hpp>
 #include <mapnik/symbolizer.hpp>
 #include <mapnik/text/placements/dummy.hpp>
 #include <mapnik/text/formatting/text.hpp>
-#include <vector>
-#include <algorithm>
-#include <mapnik/make_unique.hpp>
 
 TEST_CASE("fontset") {
 
@@ -38,8 +30,6 @@ SECTION("error") {
         mapnik::transcoder tr("utf-8");
         mapnik::value_unicode_string ustr = tr.transcode("hello world!");
         feature->put("name",ustr);
-        //auto pt = 
std::make_unique<mapnik::geometry_type>(mapnik::geometry::geometry_types::Point);
-        //pt->move_to(128,128);
         mapnik::geometry::point<double> pt(128,128);
         feature->set_geometry(std::move(pt));
 
diff --git a/test/unit/geometry/geometry.cpp b/test/unit/geometry/geometry.cpp
index 4e0598a..d42f0ab 100644
--- a/test/unit/geometry/geometry.cpp
+++ b/test/unit/geometry/geometry.cpp
@@ -1,7 +1,6 @@
 #include "catch.hpp"
 
 #include <mapnik/geometry.hpp>
-#include <mapnik/util/fs.hpp>
 #include <mapnik/util/file_io.hpp>
 #include <mapnik/json/geometry_parser.hpp>
 #include <mapnik/util/geometry_to_geojson.hpp>
diff --git a/test/unit/geometry/geometry_converters_test.cpp 
b/test/unit/geometry/geometry_converters_test.cpp
deleted file mode 100644
index 3689051..0000000
--- a/test/unit/geometry/geometry_converters_test.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include "catch.hpp"
-
-#include <iostream>
-#include <vector>
-#include <algorithm>
-
-#include <mapnik/layer.hpp>
-#include <mapnik/feature_type_style.hpp>
-#include <mapnik/rule.hpp>
-#include <mapnik/debug.hpp>
-#include <mapnik/view_transform.hpp>
-#include <mapnik/feature.hpp>
-#include <mapnik/vertex_converters.hpp>
-#include <mapnik/wkt/wkt_factory.hpp>
-#include <mapnik/well_known_srs.hpp>
-#include <mapnik/wkt/wkt_generator_grammar.hpp>
-#include <mapnik/projection.hpp>
-#include <mapnik/proj_transform.hpp>
-
-// stl
-#include <stdexcept>
-#if 0 // FIXME
-struct output_geometry_backend
-{
-    output_geometry_backend(mapnik::geometry_container & paths, 
mapnik::geometry_type::types type)
-        : paths_(paths),
-          type_(type) {}
-
-    template <typename T>
-    void add_path(T & path)
-    {
-        mapnik::vertex2d vtx(mapnik::vertex2d::no_init);
-        path.rewind(0);
-        std::unique_ptr<mapnik::geometry_type> geom_ptr(new 
mapnik::geometry_type(type_));
-
-        while ((vtx.cmd = path.vertex(&vtx.x, &vtx.y)) != mapnik::SEG_END)
-        {
-            //std::cerr << vtx.x << "," << vtx.y << "   cmd=" << vtx.cmd << 
std::endl;
-            geom_ptr->push_vertex(vtx.x, vtx.y, (mapnik::CommandType)vtx.cmd);
-        }
-        paths_.push_back(geom_ptr.release());
-    }
-    mapnik::geometry_container &  paths_;
-    mapnik::geometry_type::types type_;
-};
-
-boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> 
bbox,
-                                                      std::string wkt_in)
-{
-    using namespace mapnik;
-    agg::trans_affine tr;
-    projection src(MAPNIK_LONGLAT_PROJ);
-    projection dst(MAPNIK_LONGLAT_PROJ);
-    proj_transform prj_trans(src,dst);
-    line_symbolizer sym;
-    view_transform t(bbox.width(),bbox.height(), bbox);
-    mapnik::geometry_container output_paths;
-    output_geometry_backend backend(output_paths, 
mapnik::geometry::geometry_types::LineString);
-
-    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
-    mapnik::feature_impl f(ctx,0);
-    vertex_converter<output_geometry_backend,clip_line_tag>
-        converter(bbox, backend, sym, t, prj_trans, tr, f, attributes(), 1.0);
-
-    converter.set<clip_line_tag>();
-
-    mapnik::geometry_container p;
-    if (!mapnik::from_wkt(wkt_in , p))
-    {
-        throw std::runtime_error("Failed to parse WKT");
-    }
-
-    for (geometry_type const& geom : p)
-    {
-        vertex_adapter va(geom);
-        converter.apply(va);
-    }
-
-    using sink_type = std::back_insert_iterator<std::string>;
-    std::string wkt;
-    sink_type sink(wkt);
-    static const mapnik::wkt::wkt_multi_generator<sink_type, 
mapnik::geometry_container> generator;
-    if (boost::spirit::karma::generate(sink, generator, output_paths))
-    {
-        return boost::optional<std::string>(wkt);
-    }
-    return boost::optional<std::string>();
-}
-
-boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
-                                                   std::string wkt_in)
-{
-    using namespace mapnik;
-    agg::trans_affine tr;
-    projection src(MAPNIK_LONGLAT_PROJ);
-    projection dst(MAPNIK_LONGLAT_PROJ);
-    proj_transform prj_trans(src,dst);
-    polygon_symbolizer sym;
-    view_transform t(bbox.width(),bbox.height(), bbox);
-    mapnik::geometry_container output_paths;
-    output_geometry_backend backend(output_paths, 
mapnik::geometry::geometry_types::Polygon);
-
-    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
-    mapnik::feature_impl f(ctx,0);
-    vertex_converter<output_geometry_backend, clip_poly_tag>
-        converter(bbox, backend, sym, t, prj_trans, tr, f, attributes(), 1.0);
-
-    converter.set<clip_poly_tag>();
-
-    mapnik::geometry_container p;
-    if (!mapnik::from_wkt(wkt_in , p))
-    {
-        throw std::runtime_error("Failed to parse WKT");
-    }
-
-    for (geometry_type const& geom : p)
-    {
-        vertex_adapter va(geom);
-        converter.apply(va);
-    }
-
-    using sink_type = std::back_insert_iterator<std::string>;
-    std::string wkt; // Use Python String directly ?
-    sink_type sink(wkt);
-    static const mapnik::wkt::wkt_multi_generator<sink_type, 
mapnik::geometry_container> generator;
-    if (boost::spirit::karma::generate(sink, generator, output_paths))
-    {
-        return boost::optional<std::string>(wkt);
-    }
-
-    return boost::optional<std::string>();
-}
-
-#endif
-
-TEST_CASE("geometry converters") {
-
-SECTION("TODO") {
-
-    try
-    {
-#if 0
-        // LineString/bbox clipping
-        {
-            std::string wkt_in("LineString(0 0,200 200)");
-            boost::optional<std::string> result = 
linestring_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
-            REQUIRE(result);
-            REQUIRE(*result == std::string("LineString(50 50,150 150)"));
-        }
-        // Polygon/bbox clipping
-        {
-            std::string wkt_in("Polygon((50 50,150 50,150 150,50 150,50 50))");
-            boost::optional<std::string> result = 
polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
-            REQUIRE(result);
-            // TODO - the extra 50 50 is not ideal, but we enforce this result 
for now to prevent
-            // regressions and because we don't have actionable solution to 
drop extra 50 50
-            REQUIRE(*result == std::string("Polygon((50 50,150 50,150 150,50 
150,50 50,50 50))"));
-            // below is ideal, but not current result
-            //REQUIRE(*result == std::string("Polygon((50 50,150 50,150 150,50 
150,50 50))"));
-        }
-
-        {
-            std::string wkt_in("Polygon((60 60,140 60,140 160,60 140,60 60))");
-            boost::optional<std::string> result = 
polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
-            REQUIRE(result);
-            REQUIRE(*result == std::string("Polygon((60 60,140 60,140 150,100 
150,60 140,60 60,60 60))"));
-            //REQUIRE(*result == std::string("Polygon((60 60,140 60,140 160,60 
140,60 60))"));
-        }
-
-        {
-            std::string wkt_in("Polygon((0 0,10 0,10 10,0 10,0 0))");
-            boost::optional<std::string> result = 
polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
-            REQUIRE(result);
-            // TODO - this is completely wrong: should not have )) and ideally 
should be EMPTY
-            REQUIRE(*result == std::string("Polygon())"));
-        }
-        {
-            std::string wkt_in("Polygon((0 0,100 200,200 0,0 0 ))");
-            boost::optional<std::string> result = 
polygon_bbox_clipping(mapnik::box2d<double>(50,50,150,150),wkt_in);
-            REQUIRE(result);
-            REQUIRE(*result ==  std::string("Polygon((50 50,50 100,75 150,125 
150,150 100,150 50))"));
-            //REQUIRE(*result == std::string("Polygon((50 50,50 100,75 150,125 
150,150 100,150 50,50 50))"));
-        }
-#endif
-    }
-    catch (std::exception const & ex)
-    {
-        std::clog << ex.what() << "\n";
-        REQUIRE(false);
-    }
-}
-}
diff --git a/test/unit/geometry/geometry_envelope_test.cpp 
b/test/unit/geometry/geometry_envelope_test.cpp
index 0b7087c..d23c976 100644
--- a/test/unit/geometry/geometry_envelope_test.cpp
+++ b/test/unit/geometry/geometry_envelope_test.cpp
@@ -1,8 +1,6 @@
 #include "catch.hpp"
 
-#include <mapnik/config.hpp>
 #include <mapnik/geometry.hpp>
-#include <mapnik/geometry_adapters.hpp>
 #include <mapnik/geometry_envelope.hpp>
 #include <mapnik/geometry_correct.hpp>
 
diff --git a/test/unit/geometry/geometry_is_simple.cpp 
b/test/unit/geometry/geometry_is_simple.cpp
index a09332f..dbed04a 100644
--- a/test/unit/geometry/geometry_is_simple.cpp
+++ b/test/unit/geometry/geometry_is_simple.cpp
@@ -2,7 +2,6 @@
 
 #include <boost/version.hpp>
 #include <mapnik/geometry.hpp>
-#include <mapnik/geometry_adapters.hpp>
 #include <mapnik/geometry_is_simple.hpp>
 
 TEST_CASE("geometry is_simple") {
diff --git a/test/unit/geometry/geometry_is_valid.cpp 
b/test/unit/geometry/geometry_is_valid.cpp
index 85577ec..6d8b922 100644
--- a/test/unit/geometry/geometry_is_valid.cpp
+++ b/test/unit/geometry/geometry_is_valid.cpp
@@ -1,7 +1,6 @@
 #include "catch.hpp"
 
 #include <mapnik/geometry.hpp>
-#include <mapnik/geometry_adapters.hpp>
 #include <mapnik/geometry_is_valid.hpp>
 
 TEST_CASE("geometry is_valid") {
diff --git a/test/unit/geometry/geometry_reprojection.cpp 
b/test/unit/geometry/geometry_reprojection.cpp
index 1a52129..dad9e29 100644
--- a/test/unit/geometry/geometry_reprojection.cpp
+++ b/test/unit/geometry/geometry_reprojection.cpp
@@ -6,10 +6,6 @@
 #include <mapnik/projection.hpp>
 #include <mapnik/proj_transform.hpp>
 #include <mapnik/geometry_reprojection.hpp>
-#include <mapnik/geometry_correct.hpp>
-
-// std
-#include <iostream>
 
 TEST_CASE("geometry reprojection") {
 
diff --git a/test/unit/geometry/label_algo_test.cpp 
b/test/unit/geometry/label_algo_test.cpp
index 851db33..1c315ca 100644
--- a/test/unit/geometry/label_algo_test.cpp
+++ b/test/unit/geometry/label_algo_test.cpp
@@ -2,64 +2,32 @@
 
 #include <iostream>
 #include <mapnik/geometry.hpp>
-#include <mapnik/geometry_adapters.hpp>
 #include <mapnik/geometry_centroid.hpp>
-#include <vector>
 #include <algorithm>
 
 TEST_CASE("labeling") {
 
 SECTION("algorithms") {
 
-    try
+    // reused these for simplicity
+    mapnik::geometry::point<double> centroid;
     {
-        // reused these for simplicity
-        mapnik::geometry::point<double> centroid;
-        {
-            // single point
-            mapnik::geometry::point<double> pt(10,10);
-            REQUIRE( mapnik::geometry::centroid(pt, centroid));
-            REQUIRE( pt.x == centroid.x);
-            REQUIRE( pt.y == centroid.y);
-        }
-
-        // linestring with three consecutive verticies
-        {
-            mapnik::geometry::line_string<double> line;
-            line.add_coord(0, 0);
-            line.add_coord(25, 25);
-            line.add_coord(50, 50);
-            REQUIRE(mapnik::geometry::centroid(line, centroid));
-            REQUIRE( centroid.x == 25 );
-            REQUIRE( centroid.y == 25 );
-        }
-        // TODO - centroid and interior should be equal but they appear not to 
be (check largest)
-        // MULTIPOLYGON(((-52 40,-60 32,-68 40,-60 48,-52 40)),((-60 50,-80 
30,-100 49.9999999999999,-80.0000000000001 70,-60 50)),((-52 60,-60 52,-68 
60,-60 68,-52 60)))
-#if 0
-        // hit tests
-        {
-            mapnik::geometry_type 
pt_hit(mapnik::geometry::geometry_types::Point);
-            pt_hit.move_to(10,10);
-            mapnik::vertex_adapter va(pt_hit);
-            REQUIRE( mapnik::label::hit_test(va, 10, 10, 0.1) );
-            REQUIRE( !mapnik::label::hit_test(va, 9, 9, 0) );
-            REQUIRE( mapnik::label::hit_test(va, 9, 9, 1.5) );
-        }
-        {
-            mapnik::geometry_type 
line_hit(mapnik::geometry::geometry_types::LineString);
-            line_hit.move_to(0,0);
-            line_hit.line_to(50,50);
-            mapnik::vertex_adapter va(line_hit);
-            REQUIRE( mapnik::label::hit_test(va, 0, 0, 0.001) );
-            REQUIRE( !mapnik::label::hit_test(va, 1, 1, 0) );
-            REQUIRE( mapnik::label::hit_test(va, 1, 1, 1.001) );
-        }
-#endif
+        // single point
+        mapnik::geometry::point<double> pt(10,10);
+        REQUIRE( mapnik::geometry::centroid(pt, centroid));
+        REQUIRE( pt.x == centroid.x);
+        REQUIRE( pt.y == centroid.y);
     }
-    catch (std::exception const & ex)
+
+    // linestring with three consecutive verticies
     {
-        std::clog << ex.what() << "\n";
-        REQUIRE(false);
+        mapnik::geometry::line_string<double> line;
+        line.add_coord(0, 0);
+        line.add_coord(25, 25);
+        line.add_coord(50, 50);
+        REQUIRE(mapnik::geometry::centroid(line, centroid));
+        REQUIRE( centroid.x == 25 );
+        REQUIRE( centroid.y == 25 );
     }
 }
 }
diff --git a/test/unit/imaging/image.cpp b/test/unit/imaging/image.cpp
index 23f02c2..9800860 100644
--- a/test/unit/imaging/image.cpp
+++ b/test/unit/imaging/image.cpp
@@ -1,10 +1,10 @@
 #include "catch.hpp"
 
 // mapnik
-#include <mapnik/value.hpp>
+#include <mapnik/image.hpp>
+#include <mapnik/image_view.hpp>
 #include <mapnik/image_any.hpp>
 #include <mapnik/color.hpp>
-#include <mapnik/image_view_any.hpp>
 #include <mapnik/image_util.hpp>
 
 TEST_CASE("image class") {
@@ -341,8 +341,7 @@ SECTION("Image copy/move")
         CHECK( pixel == mapnik::color(0,255,0).rgba());
     }
 
-    // deep copy
-    mapnik::image_rgba8 im3(im2); // allocates new internal buffer
+    mapnik::image_rgba8 im3(im2); // shallow copy
     for (auto & pixel : im3)
     {
         // expect `green`
@@ -351,22 +350,15 @@ SECTION("Image copy/move")
         pixel = mapnik::color(255,0,0).rgba(); //red
     }
 
-    // im2 (green)
-    for (auto const& pixel : im2)
+    for (auto const& pixel : im3)
     {
-        // expect `green`
-        CHECK( pixel == mapnik::color(0,255,0).rgba());
+        // expect `red`
+        CHECK( pixel == mapnik::color(255,0,0).rgba());
     }
-
-    //buf2 still holds green pixels
-    CHECK(buf2.size() == 16 * 16 * 4);
-
-    unsigned char* itr = buf2.data();
-    unsigned char* end = itr + buf2.size();
-    count = 0;
-    for ( ;itr!= end; ++itr)
+    for (auto const& pixel : im2)
     {
-        CHECK( *itr == ((count++ % 2 == 0) ? 0 : 0xff)); // green
+        // expect `red`
+        CHECK( pixel == mapnik::color(255,0,0).rgba());
     }
 }
 
diff --git a/test/unit/imaging/image_io_test.cpp 
b/test/unit/imaging/image_io_test.cpp
index 8a51502..37f8fee 100644
--- a/test/unit/imaging/image_io_test.cpp
+++ b/test/unit/imaging/image_io_test.cpp
@@ -6,8 +6,6 @@
 #include <mapnik/image_util.hpp>
 #include <mapnik/image_util_jpeg.hpp>
 #include <mapnik/util/fs.hpp>
-#include <vector>
-#include <algorithm>
 #if defined(HAVE_CAIRO)
 #include <mapnik/cairo/cairo_context.hpp>
 #include <mapnik/cairo/cairo_image_util.hpp>
diff --git a/test/unit/imaging/image_set_pixel.cpp 
b/test/unit/imaging/image_set_pixel.cpp
index ed7ceaf..3488e00 100644
--- a/test/unit/imaging/image_set_pixel.cpp
+++ b/test/unit/imaging/image_set_pixel.cpp
@@ -1,9 +1,7 @@
 #include "catch.hpp"
 
 // mapnik
-#include <mapnik/image_any.hpp>
-#include <mapnik/image_view_any.hpp>
-#include <mapnik/color.hpp>
+#include <mapnik/image.hpp>
 #include <mapnik/image_util.hpp>
 
 
diff --git a/test/unit/imaging/image_view.cpp b/test/unit/imaging/image_view.cpp
index dac7644..25dbacf 100644
--- a/test/unit/imaging/image_view.cpp
+++ b/test/unit/imaging/image_view.cpp
@@ -1,7 +1,7 @@
 #include "catch.hpp"
 
 // mapnik
-#include <mapnik/image_any.hpp>
+#include <mapnik/image.hpp>
 #include <mapnik/color.hpp>
 #include <mapnik/image_view_any.hpp>
 #include <mapnik/image_util.hpp>
diff --git a/test/unit/imaging/tiff_io.cpp b/test/unit/imaging/tiff_io.cpp
index 2e31d56..1ace38f 100644
--- a/test/unit/imaging/tiff_io.cpp
+++ b/test/unit/imaging/tiff_io.cpp
@@ -7,10 +7,8 @@
 #include "catch.hpp"
 
 #include <mapnik/image_reader.hpp>
-#include <mapnik/image_util.hpp>
 #include <mapnik/util/file_io.hpp>
 
-#include <mapnik/tiff_io.hpp>
 #include "../../../src/tiff_reader.cpp"
 
 #define TIFF_ASSERT(filename) \
diff --git a/test/unit/imaging/webp_io.cpp b/test/unit/imaging/webp_io.cpp
index 6f580a4..8f6d23b 100644
--- a/test/unit/imaging/webp_io.cpp
+++ b/test/unit/imaging/webp_io.cpp
@@ -3,8 +3,7 @@
 
 #include "catch.hpp"
 
-#include <mapnik/image_util.hpp>
-#include <mapnik/image_view_any.hpp>
+#include <mapnik/image_view.hpp>
 #include <mapnik/webp_io.hpp>
 
 TEST_CASE("webp io") {
diff --git a/test/unit/pixel/agg_blend_src_over_test.cpp 
b/test/unit/pixel/agg_blend_src_over_test.cpp
index 235a230..60846f7 100644
--- a/test/unit/pixel/agg_blend_src_over_test.cpp
+++ b/test/unit/pixel/agg_blend_src_over_test.cpp
@@ -1,12 +1,9 @@
 #include "catch.hpp"
 
 #include <iostream>
-#include <cstdio>
 #include <cstring>
 #include <sstream>
 #include <string>
-#include <vector>
-#include <algorithm>
 #include "agg_color_rgba.h"
 #include "agg_pixfmt_rgba.h"
 #include "agg_rendering_buffer.h"
diff --git a/test/unit/serialization/wkb_formats_test.cpp 
b/test/unit/serialization/wkb_formats_test.cpp
index ff72a1c..1f3a82e 100644
--- a/test/unit/serialization/wkb_formats_test.cpp
+++ b/test/unit/serialization/wkb_formats_test.cpp
@@ -1,15 +1,12 @@
 #include "catch.hpp"
 
 #include <iostream>
-#include <mapnik/params.hpp>
 #include <mapnik/wkb.hpp>
 #include <mapnik/feature.hpp>
 #include <mapnik/geometry_is_valid.hpp>
 #include <mapnik/geometry_is_simple.hpp>
 #include <mapnik/geometry_correct.hpp>
 #include <mapnik/feature_factory.hpp>
-#include <vector>
-#include <algorithm>
 #include <boost/version.hpp>
 
 TEST_CASE("geometry formats") {
diff --git a/test/unit/serialization/xml_parser_trim.cpp 
b/test/unit/serialization/xml_parser_trim.cpp
index f79c755..afd2824 100644
--- a/test/unit/serialization/xml_parser_trim.cpp
+++ b/test/unit/serialization/xml_parser_trim.cpp
@@ -1,10 +1,8 @@
 #include "catch.hpp"
 
-#include <mapnik/debug.hpp>
-#include <mapnik/value.hpp>
 #include <mapnik/xml_tree.hpp>
 #include <mapnik/xml_loader.hpp>
-#include <mapnik/attribute.hpp>
+#include <mapnik/attribute.hpp> // needed due to fwd declare in value_types.hpp
 
 TEST_CASE("xml parser") {
 
diff --git a/test/unit/svg/svg_parser_test.cpp 
b/test/unit/svg/svg_parser_test.cpp
index 6dfb0bd..c92b797 100644
--- a/test/unit/svg/svg_parser_test.cpp
+++ b/test/unit/svg/svg_parser_test.cpp
@@ -22,20 +22,18 @@
 
 #include "catch.hpp"
 
-#include <mapnik/version.hpp>
 #include <mapnik/debug.hpp>
 #include <mapnik/marker.hpp>
 #include <mapnik/marker_cache.hpp>
 #include <mapnik/vertex.hpp>
 #include <mapnik/svg/svg_parser.hpp>
-#include <mapnik/svg/svg_storage.hpp>
 #include <mapnik/svg/svg_converter.hpp>
 #include <mapnik/svg/svg_path_adapter.hpp>
 #include <mapnik/svg/svg_path_attributes.hpp>
 
 #include <cmath>
 #include <fstream>
-#include <streambuf>
+#include <iterator>
 
 namespace detail {
 
diff --git a/test/unit/symbolizer/symbolizer_test.cpp 
b/test/unit/symbolizer/symbolizer_test.cpp
index 582613d..3af0532 100644
--- a/test/unit/symbolizer/symbolizer_test.cpp
+++ b/test/unit/symbolizer/symbolizer_test.cpp
@@ -2,8 +2,6 @@
 
 #include <iostream>
 #include <mapnik/symbolizer.hpp>
-#include <vector>
-#include <algorithm>
 
 using namespace mapnik;
 
diff --git a/test/unit/vertex_adapter/clipping_test.cpp 
b/test/unit/vertex_adapter/clipping_test.cpp
index 14dd06a..e2e0abd 100644
--- a/test/unit/vertex_adapter/clipping_test.cpp
+++ b/test/unit/vertex_adapter/clipping_test.cpp
@@ -17,10 +17,8 @@
 #include <sstream>
 #include <fstream>
 #include <vector>
-#include <algorithm>
 
 // agg
-#include "agg_conv_clip_polygon.h"
 #include "agg_conv_clip_polyline.h"
 
 template <typename T>
diff --git a/test/unit/vertex_adapter/line_offset_test.cpp 
b/test/unit/vertex_adapter/line_offset_test.cpp
index 6e32f72..eba472f 100644
--- a/test/unit/vertex_adapter/line_offset_test.cpp
+++ b/test/unit/vertex_adapter/line_offset_test.cpp
@@ -1,17 +1,13 @@
 #include "catch.hpp"
 
 // mapnik
-#include <mapnik/global.hpp>
-#include <mapnik/coord.hpp>
 #include <mapnik/vertex_cache.hpp>
+#include <mapnik/global.hpp>
 
 // stl
-#include <stdexcept>
 #include <iostream>
-#include <fstream>
 #include <vector>
 #include <tuple>
-#include <algorithm>
 
 struct fake_path
 {
diff --git a/test/unit/vertex_adapter/offset_converter.cpp 
b/test/unit/vertex_adapter/offset_converter.cpp
index b4b7d73..7855c60 100644
--- a/test/unit/vertex_adapter/offset_converter.cpp
+++ b/test/unit/vertex_adapter/offset_converter.cpp
@@ -1,18 +1,13 @@
 #include "catch.hpp"
 
 // mapnik
-#include <mapnik/global.hpp>
-#include <mapnik/coord.hpp>
 #include <mapnik/vertex.hpp>
 #include <mapnik/offset_converter.hpp>
 
 // stl
-#include <stdexcept>
 #include <iostream>
-#include <fstream>
 #include <vector>
 #include <tuple>
-#include <algorithm>
 
 namespace offset_test {
 
diff --git a/test/unit/vertex_adapter/simplify_converters_test.cpp 
b/test/unit/vertex_adapter/simplify_converters_test.cpp
index a5f99b2..a86f8d5 100644
--- a/test/unit/vertex_adapter/simplify_converters_test.cpp
+++ b/test/unit/vertex_adapter/simplify_converters_test.cpp
@@ -1,15 +1,9 @@
 #include "catch.hpp"
 
-#include <iostream>
-#include <vector>
-#include <string>
-#include <algorithm>
-
-#include <mapnik/layer.hpp>
-#include <mapnik/wkt/wkt_factory.hpp>
-#include <mapnik/wkt/wkt_generator_grammar.hpp>
-#include <mapnik/simplify.hpp>
-#include <mapnik/simplify_converter.hpp>
+//#include <mapnik/wkt/wkt_factory.hpp>
+//#include <mapnik/wkt/wkt_generator_grammar.hpp>
+//#include <mapnik/simplify.hpp>
+//#include <mapnik/simplify_converter.hpp>
 
 // stl
 #include <stdexcept>
diff --git a/utils/mapnik-index/process_geojson_file.cpp 
b/utils/mapnik-index/process_geojson_file.cpp
index 687edac..9a9ee93 100644
--- a/utils/mapnik-index/process_geojson_file.cpp
+++ b/utils/mapnik-index/process_geojson_file.cpp
@@ -29,6 +29,7 @@
 
 #if defined(MAPNIK_MEMORY_MAPPED_FILE)
 #pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-local-typedef"
 #pragma GCC diagnostic ignored "-Wshadow"
 #pragma GCC diagnostic ignored "-Wsign-compare"
 #pragma GCC diagnostic ignored "-Wsign-conversion"
@@ -88,18 +89,20 @@ std::pair<bool,box2d<double>> process_geojson_file(T & 
boxes, std::string const&
         if (!boost::spirit::qi::phrase_parse(start, end, 
(geojson_datasource_static_bbox_grammar)(boost::phoenix::ref(boxes)) , space))
         {
             std::clog << "mapnik-index (GeoJSON) : could extract bounding 
boxes from : '" <<  filename <<  "'";
-            std::clog << " expected FeatureCollection" << std::endl;
             return std::make_pair(false, extent);
         }
     }
     catch (std::exception const& ex)
     {
-        std::clog << "mapnik-index:" << ex.what() << std::endl;
+        std::clog << "mapnik-index (GeoJSON): " << ex.what() << std::endl;
     }
     for (auto const& item : boxes)
     {
-        if (!extent.valid()) extent = item.first;
-        else extent.expand_to_include(item.first);
+        if (item.first.valid())
+        {
+            if (!extent.valid()) extent = item.first;
+            else extent.expand_to_include(item.first);
+        }
     }
     return std::make_pair(true, extent);
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-grass/mapnik.git

_______________________________________________
Pkg-grass-devel mailing list
Pkg-grass-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

Reply via email to