diff --git a/README.md b/README.md index 18268deb6..b5ebf6a3e 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ _/ _/ _/_/_/ _/_/_/ _/ _/ _/ _/ _/ _/ ``` -[![Build Status Linux](https://secure.travis-ci.org/mapnik/mapnik.png)](http://travis-ci.org/mapnik/mapnik) -[![Build status Windows](https://ci.appveyor.com/api/projects/status/hc9l7okdjtucfqqn?svg=true)](https://ci.appveyor.com/project/Mapbox/mapnik) +[![Build Status Linux](https://api.travis-ci.org/mapnik/mapnik.svg?branch=master)](http://travis-ci.org/mapnik/mapnik) +[![Build Status Windows](https://ci.appveyor.com/api/projects/status/hc9l7okdjtucfqqn?branch=master&svg=true)](https://ci.appveyor.com/project/Mapbox/mapnik) [![Coverage Status](https://coveralls.io/repos/mapnik/mapnik/badge.svg?branch=master&service=github)](https://coveralls.io/github/mapnik/mapnik?branch=master) Mapnik is an open source toolkit for developing mapping applications. At the core is a C++ shared library providing algorithms and patterns for spatial data access and visualization. diff --git a/scripts/appveyor-system-info.ps1 b/scripts/appveyor-system-info.ps1 index 550cfb530..586ef2de2 100644 --- a/scripts/appveyor-system-info.ps1 +++ b/scripts/appveyor-system-info.ps1 @@ -1,6 +1,16 @@ $PSVersionTable $PSVersionTable.PSVersion +$comp_name = $env:COMPUTERNAME +$user_name = $env:USERNAME +Write-Host $comp_name $user_name + +$on_appveyor = $false +if($comp_name -like 'APPVYR*' -And $user_name -eq "appveyor"){ + $on_appveyor = $true +} + + $SystemManaged = Get-WmiObject -Class Win32_ComputerSystem | % {$_.AutomaticManagedPagefile} $total_physicalmem = gwmi Win32_ComputerSystem | % {[Math]::round($_.TotalPhysicalMemory/1MB,0)} $physical_mem = get-ciminstance -class 'cim_physicalmemory' | % { $_.Capacity/1024/1024} @@ -17,8 +27,25 @@ Write-Host "page file size : "$PageFileSize Write-Host "InitialSize : "${CurrentPageFile}.InitialSize Write-Host "MaximumSize : "$CurrentPageFile.MaximumSize -if($env:APPVEYOR -eq "true"){ +if($on_appveyor -eq $true){ + Write-Host !!!!!!! on AppVeyor: changing page file settings !!!!!!!!!! + + $dirs = ( + "C:\qt", + "C:\Users\appveyor\AppData\Local\Microsoft\Web Platform Installer", + "C:\Program Files\Microsoft SQL Server", + "C:\ProgramData\Package Cache" + ) + Foreach($dir in $dirs){ + if(Test-Path $dir) { + Write-Host found $dir + Remove-Item $dir -Force -Recurse + } else { + Write-Host not found $dir + } + } + #disable automatically managed page file settings $c = Get-WmiObject Win32_computersystem -EnableAllPrivileges if($c.AutomaticManagedPagefile){ diff --git a/test/catch_ext.hpp b/test/catch_ext.hpp new file mode 100644 index 000000000..3168ecf43 --- /dev/null +++ b/test/catch_ext.hpp @@ -0,0 +1,22 @@ +#ifndef TEST_CATCH_EXT_HPP +#define TEST_CATCH_EXT_HPP + +#include "catch.hpp" + +#define TRY_CHECK( expr ) \ + try { \ + CHECK( expr ); \ + } \ + catch ( Catch::TestFailureException & ) { \ + /* thrown by CHECK after it catches and reports */ \ + /* an exception from expr => swallow this */ \ + } + +#define TRY_CHECK_FALSE( expr ) \ + try { \ + CHECK_FALSE( expr ); \ + } \ + catch ( Catch::TestFailureException & ) { \ + } + +#endif // TEST_CATCH_EXT_HPP diff --git a/test/unit/core/expressions_test.cpp b/test/unit/core/expressions_test.cpp new file mode 100644 index 000000000..75eba6217 --- /dev/null +++ b/test/unit/core/expressions_test.cpp @@ -0,0 +1,149 @@ +#include "catch_ext.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +template +mapnik::feature_ptr make_test_feature(mapnik::value_integer id, std::string const& wkt, Properties const& prop) +{ + auto ctx = std::make_shared(); + mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, id)); + mapnik::geometry::geometry geom; + if (mapnik::from_wkt(wkt, geom)) + { + feature->set_geometry(std::move(geom)); + } + + for (auto const& kv : prop) + { + feature->put_new(kv.first, kv.second); + } + return feature; +} + +template +mapnik::value_type evaluate(Feature const& feature, Expression const& expr) +{ + auto value = mapnik::util::apply_visitor( + mapnik::evaluate( + feature, mapnik::attributes()), expr); + return value; +} + +mapnik::value evaluate_string(mapnik::feature_ptr const& feature, std::string const& str) +{ + auto expr = mapnik::parse_expression(str); + return evaluate(*feature, *expr); +} + +std::string parse_and_dump(std::string const& str) +{ + auto expr = mapnik::parse_expression(str); + return mapnik::to_expression_string(*expr); +} + +} // namespace + +TEST_CASE("expressions") +{ + using namespace std::placeholders; + using properties_type = std::vector > ; + mapnik::transcoder tr("utf8"); + + properties_type prop = {{ "foo" , tr.transcode("bar") }, + { "name" , tr.transcode("Québec")}, + { "double", mapnik::value_double(1.23456)}, + { "int" , mapnik::value_integer(123)}, + { "bool" , mapnik::value_bool(true)}, + { "null" , mapnik::value_null()}}; + + auto feature = make_test_feature(1, "POINT(100 200)", prop); + auto eval = std::bind(evaluate_string, feature, _1); + auto approx = Approx::custom().epsilon(1e-6); + + TRY_CHECK(eval(" [foo]='bar' ") == true); + + // primary expressions + // null + TRY_CHECK(parse_and_dump("null") == "null"); + // boolean + TRY_CHECK(parse_and_dump("true") == "true"); + TRY_CHECK(parse_and_dump("false") == "false"); + // floating point + TRY_CHECK(parse_and_dump("3.14159") == "3.14159"); + // integer + TRY_CHECK(parse_and_dump("123") == "123"); + // unicode + TRY_CHECK(parse_and_dump("'single-quoted string'") == "'single-quoted string'"); + TRY_CHECK(parse_and_dump("\"double-quoted string\"") == "'double-quoted string'"); + + // floating point constants + TRY_CHECK(parse_and_dump("pi") == "3.14159"); + TRY_CHECK(parse_and_dump("deg_to_rad") == "0.0174533"); + TRY_CHECK(parse_and_dump("rad_to_deg") == "57.2958"); + + // unary functions + // sin / cos + TRY_CHECK(eval(" sin(0.25 * pi) / cos(0.25 * pi) ").to_double() == approx(1.0)); + // tan + TRY_CHECK(eval(" tan(0.25 * pi) ").to_double() == approx(1.0)); + // atan + TRY_CHECK(eval(" rad_to_deg * atan(1.0) ").to_double() == approx(45.0)); + // exp + TRY_CHECK(eval(" exp(0.0) ") == 1.0); + // abs + TRY_CHECK(eval(" abs(cos(-pi)) ") == 1.0); + // length (string) + TRY_CHECK(eval(" length('1234567890') ").to_int() == 10); + + // binary functions + // min + TRY_CHECK(eval(" min(-0.01, 0.001) ") == -0.01); + // max + TRY_CHECK(eval(" max(0.01, -0.1) ") == 0.01); + // pow + TRY_CHECK(eval(" pow(2, 32) ") == 4294967296.0); + + // geometry types + TRY_CHECK(eval(" [mapnik::geometry_type] = point ") == true); + TRY_CHECK(eval(" [mapnik::geometry_type] <> linestring ") == true); + TRY_CHECK(eval(" [mapnik::geometry_type] != polygon ") == true); + TRY_CHECK(eval(" [mapnik::geometry_type] neq collection ") == true); + TRY_CHECK(eval(" [mapnik::geometry_type] eq collection ") == false); + + //unary expression + TRY_CHECK(eval(" -123.456 ") == -123.456); + TRY_CHECK(eval(" +123.456 ") == 123.456); + + // multiplicative/additive + auto expr = mapnik::parse_expression("(2.0 * 2.0 + 3.0 * 3.0)/(2.0 * 2.0 - 3.0 * 3.0)"); + TRY_CHECK(evaluate(*feature, *expr) == -2.6); + auto expr2 = mapnik::parse_expression("(2.0 * 2.0 + 3.0 * 3.0)/((2.0 - 3.0) * (2.0 + 3.0))"); + TRY_CHECK(evaluate(*feature, *expr) == evaluate(*feature, *expr2)); + + // logical + TRY_CHECK(eval(" [int] = 123 and [double] = 1.23456 && [bool] = true and [null] = null && [foo] = 'bar' ") == true); + TRY_CHECK(eval(" [int] = 456 or [foo].match('foo') || length([foo]) = 3 ") == true); + + // relational + TRY_CHECK(eval(" [int] > 100 and [int] gt 100.0 and [double] < 2 and [double] lt 2.0 ") == true); + TRY_CHECK(eval(" [int] >= 123 and [int] ge 123.0 and [double] <= 1.23456 and [double] le 1.23456 ") == true); + + // regex + // replace + TRY_CHECK(eval(" [foo].replace('(\\B)|( )','$1 ') ") == tr.transcode("b a r")); + + // match + TRY_CHECK(eval(" [name].match('Québec') ") == true); + +} diff --git a/test/unit/core/expresssions_test.cpp b/test/unit/core/expresssions_test.cpp deleted file mode 100644 index 309d9a068..000000000 --- a/test/unit/core/expresssions_test.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include "catch.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - -template -mapnik::feature_ptr make_test_feature(mapnik::value_integer id, std::string const& wkt, Properties const& prop) -{ - auto ctx = std::make_shared(); - mapnik::feature_ptr feature(mapnik::feature_factory::create(ctx, id)); - mapnik::geometry::geometry geom; - if (mapnik::from_wkt(wkt, geom)) - { - feature->set_geometry(std::move(geom)); - } - - for (auto const& kv : prop) - { - feature->put_new(kv.first, kv.second); - } - return feature; -} - -template -mapnik::value_type evaluate(Feature const& feature, Expression const& expr) -{ - auto value = mapnik::util::apply_visitor( - mapnik::evaluate( - feature, mapnik::attributes()), expr); - return value; -} - -} -TEST_CASE("expressions") -{ - using properties_type = std::vector > ; - mapnik::transcoder tr("utf8"); - - properties_type prop = {{ "foo" , tr.transcode("bar") }, - { "name" , tr.transcode("Québec")}, - { "double", mapnik::value_double(1.23456)}, - { "int" , mapnik::value_integer(123)}, - { "bool" , mapnik::value_bool(true)}, - { "null" , mapnik::value_null()}}; - - auto feature = make_test_feature(1, "POINT(100 200)", prop); - - auto expr = mapnik::parse_expression("[foo]='bar'"); - REQUIRE(evaluate(*feature, *expr) == true); - - // primary expressions - // null - expr = mapnik::parse_expression("null"); - REQUIRE(mapnik::to_expression_string(*expr) == "null"); - // boolean - expr = mapnik::parse_expression("true"); - REQUIRE(mapnik::to_expression_string(*expr) == "true"); - expr = mapnik::parse_expression("false"); - REQUIRE(mapnik::to_expression_string(*expr) == "false"); - // floating point - expr = mapnik::parse_expression("3.14159"); - REQUIRE(mapnik::to_expression_string(*expr) == "3.14159"); - // integer - expr = mapnik::parse_expression("123"); - REQUIRE(mapnik::to_expression_string(*expr) == "123"); - // unicode - expr = mapnik::parse_expression("'single_quoted_string'"); - REQUIRE(mapnik::to_expression_string(*expr) == "'single_quoted_string'"); - expr = mapnik::parse_expression("\"double_quoted_string\""); - REQUIRE(mapnik::to_expression_string(*expr) == "'double_quoted_string'"); - - // floating point constants - expr = mapnik::parse_expression("pi"); - REQUIRE(mapnik::to_expression_string(*expr) == "3.14159"); - expr = mapnik::parse_expression("deg_to_rad"); - REQUIRE(mapnik::to_expression_string(*expr) == "0.0174533"); - expr = mapnik::parse_expression("rad_to_deg"); - REQUIRE(mapnik::to_expression_string(*expr) == "57.2958"); - - // unary functions - // sin / cos - expr = mapnik::parse_expression("sin(0.25 * pi)/cos(0.25 * pi)"); - double value = evaluate(*feature, *expr).to_double(); - REQUIRE(std::fabs(value - 1.0) < 1e-6); - // tan - auto expr2 = mapnik::parse_expression("tan(0.25 * pi)"); - double value2 = evaluate(*feature, *expr).to_double(); - REQUIRE(value == value2); - // atan - expr = mapnik::parse_expression("rad_to_deg * atan(1.0)"); - REQUIRE(std::fabs(evaluate(*feature, *expr).to_double() - 45.0) < 1e-6); - // exp - expr = mapnik::parse_expression("exp(0.0)"); - REQUIRE(evaluate(*feature, *expr).to_double() == 1.0); - // abs - expr = mapnik::parse_expression("abs(cos(-pi))"); - REQUIRE(evaluate(*feature, *expr).to_double() == 1.0); - // length (string) - expr = mapnik::parse_expression("length('1234567890')"); - REQUIRE(evaluate(*feature, *expr).to_int() == 10); - - // binary functions - // min - expr = mapnik::parse_expression("min(-0.01, 0.001)"); - REQUIRE(evaluate(*feature, *expr).to_double() == -0.01); - // max - expr = mapnik::parse_expression("max(0.01, -0.1)"); - REQUIRE(evaluate(*feature, *expr).to_double() == 0.01); - // pow - expr = mapnik::parse_expression("pow(2, 32)"); - REQUIRE(evaluate(*feature, *expr).to_double() == 4294967296.0); - - // geometry types - expr = mapnik::parse_expression("[mapnik::geometry_type] = point"); - REQUIRE(evaluate(*feature, *expr) == true); - expr = mapnik::parse_expression("[mapnik::geometry_type] <> linestring"); - REQUIRE(evaluate(*feature, *expr) == true); - expr = mapnik::parse_expression("[mapnik::geometry_type] != polygon"); - REQUIRE(evaluate(*feature, *expr) == true); - expr = mapnik::parse_expression("[mapnik::geometry_type] neq collection"); - REQUIRE(evaluate(*feature, *expr) == true); - expr = mapnik::parse_expression("[mapnik::geometry_type] eq collection"); - REQUIRE(evaluate(*feature, *expr) == false); - - //unary expression - expr = mapnik::parse_expression("-123.456"); - REQUIRE(evaluate(*feature, *expr).to_double() == -123.456); - expr = mapnik::parse_expression("+123.456"); - REQUIRE(evaluate(*feature, *expr).to_double() == 123.456); - - // multiplicative/additive - expr = mapnik::parse_expression("(2.0 * 2.0 + 3.0 * 3.0)/(2.0 * 2.0 - 3.0 * 3.0)"); - REQUIRE(evaluate(*feature, *expr).to_double() == -2.6); - expr2 = mapnik::parse_expression("(2.0 * 2.0 + 3.0 * 3.0)/((2.0 - 3.0) * (2.0 + 3.0))"); - REQUIRE(evaluate(*feature, *expr).to_double() == evaluate(*feature, *expr2).to_double()); - - // logical - expr = mapnik::parse_expression("[int] = 123 and [double] = 1.23456 && [bool] = true and [null] = null && [foo] = 'bar'"); - REQUIRE(evaluate(*feature, *expr) == true); - expr = mapnik::parse_expression("[int] = 456 or [foo].match('foo') || length([foo]) = 3"); - REQUIRE(evaluate(*feature, *expr) == true); - - // relational - expr = mapnik::parse_expression("[int] > 100 and [int] gt 100.0 and [double] < 2 and [double] lt 2.0"); - REQUIRE(evaluate(*feature, *expr) == true); - expr = mapnik::parse_expression("[int] >= 123 and [int] ge 123.0 and [double] <= 1.23456 and [double] le 1.23456"); - REQUIRE(evaluate(*feature, *expr) == true); - - // regex - // replace - expr = mapnik::parse_expression("[foo].replace('(\\B)|( )','$1 ')"); - REQUIRE(evaluate(*feature, *expr) == tr.transcode("b a r")); - - // match - expr = mapnik::parse_expression("[name].match('Québec')"); - REQUIRE(evaluate(*feature, *expr) == true); - -}