summaryrefslogtreecommitdiff
path: root/test/style/filter.cpp
blob: 53504d84aeea3282188353d1b3d9a0955c9eaf0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <mbgl/test/util.hpp>

#include <mbgl/style/filter.hpp>
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/style/rapidjson_conversion.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/filter.hpp>

#include <rapidjson/document.h>

using namespace mbgl;
using namespace mbgl::style;

Filter parse(const char * expression) {
    rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc;
    doc.Parse<0>(expression);
    return *conversion::convert<Filter>(doc);
}

bool evaluate(const Filter& filter, const PropertyMap& properties, FeatureType type = FeatureType::Unknown) {
    return filter(type, [&] (const std::string& key) -> optional<Value> {
        auto it = properties.find(key);
        if (it == properties.end())
            return {};
        return it->second;
    });
}

TEST(Filter, EqualsString) {
    Filter f = parse("[\"==\", \"foo\", \"bar\"]");
    ASSERT_TRUE(evaluate(f, {{ "foo", std::string("bar") }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", std::string("baz") }}));
}

TEST(Filter, EqualsNumber) {
    Filter f = parse("[\"==\", \"foo\", 0]");
    ASSERT_TRUE(evaluate(f, {{ "foo", int64_t(0) }}));
    ASSERT_TRUE(evaluate(f, {{ "foo", uint64_t(0) }}));
    ASSERT_TRUE(evaluate(f, {{ "foo", double(0) }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", int64_t(1) }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", uint64_t(1) }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", double(1) }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", std::string("0") }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", false }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", true }}));
    ASSERT_FALSE(evaluate(f, {{ "foo", nullptr }}));
    ASSERT_FALSE(evaluate(f, {{}}));
}

TEST(Filter, EqualsType) {
    Filter f = parse("[\"==\", \"$type\", \"LineString\"]");
    ASSERT_FALSE(evaluate(f, {{}}, FeatureType::Point));
    ASSERT_TRUE(evaluate(f, {{}}, FeatureType::LineString));
}

TEST(Filter, InType) {
    Filter f = parse("[\"in\", \"$type\", \"LineString\", \"Polygon\"]");
    ASSERT_FALSE(evaluate(f, {{}}, FeatureType::Point));
    ASSERT_TRUE(evaluate(f, {{}}, FeatureType::LineString));
    ASSERT_TRUE(evaluate(f, {{}}, FeatureType::Polygon));
}

TEST(Filter, Any) {
    ASSERT_FALSE(evaluate(parse("[\"any\"]"), {{}}));
    ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 1]]"),
                         {{ std::string("foo"), int64_t(1) }}));
    ASSERT_FALSE(evaluate(parse("[\"any\", [\"==\", \"foo\", 0]]"),
                          {{ std::string("foo"), int64_t(1) }}));
    ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
                         {{ std::string("foo"), int64_t(1) }}));
}

TEST(Filter, All) {
    ASSERT_TRUE(evaluate(parse("[\"all\"]"), {{}}));
    ASSERT_TRUE(evaluate(parse("[\"all\", [\"==\", \"foo\", 1]]"),
                         {{ std::string("foo"), int64_t(1) }}));
    ASSERT_FALSE(evaluate(parse("[\"all\", [\"==\", \"foo\", 0]]"),
                          {{ std::string("foo"), int64_t(1) }}));
    ASSERT_FALSE(evaluate(parse("[\"all\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
                          {{ std::string("foo"), int64_t(1) }}));
}

TEST(Filter, None) {
    ASSERT_TRUE(evaluate(parse("[\"none\"]"), {{}}));
    ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 1]]"),
                          {{ std::string("foo"), int64_t(1) }}));
    ASSERT_TRUE(evaluate(parse("[\"none\", [\"==\", \"foo\", 0]]"),
                         {{ std::string("foo"), int64_t(1) }}));
    ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
                          {{ std::string("foo"), int64_t(1) }}));
}

TEST(Filter, Has) {
    ASSERT_TRUE(evaluate(parse("[\"has\", \"foo\"]"),
                          {{ std::string("foo"), int64_t(1) }}));
    ASSERT_TRUE(evaluate(parse("[\"has\", \"foo\"]"),
                          {{ std::string("foo"), int64_t(0) }}));
    ASSERT_TRUE(evaluate(parse("[\"has\", \"foo\"]"),
                          {{ std::string("foo"), false }}));
    ASSERT_FALSE(evaluate(parse("[\"has\", \"foo\"]"),
                          {{}}));
}

TEST(Filter, NotHas) {
    ASSERT_FALSE(evaluate(parse("[\"!has\", \"foo\"]"),
                          {{ std::string("foo"), int64_t(1) }}));
    ASSERT_FALSE(evaluate(parse("[\"!has\", \"foo\"]"),
                          {{ std::string("foo"), int64_t(0) }}));
    ASSERT_FALSE(evaluate(parse("[\"!has\", \"foo\"]"),
                          {{ std::string("foo"), false }}));
    ASSERT_TRUE(evaluate(parse("[\"!has\", \"foo\"]"),
                          {{}}));
}