1 #include "catch.hpp" 2 3 #include <osmium/builder/attr.hpp> 4 #include <osmium/builder/builder_helper.hpp> 5 #include <osmium/memory/buffer.hpp> 6 #include <osmium/osm/tag.hpp> 7 8 #include <map> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) 14 15 TEST_CASE("create tag list") { 16 osmium::memory::Buffer buffer{10240}; 17 18 SECTION("with TagListBuilder from char*") { 19 { 20 osmium::builder::TagListBuilder builder(buffer); 21 builder.add_tag("highway", "primary"); 22 builder.add_tag("name", "Main Street"); 23 } 24 buffer.commit(); 25 } 26 27 SECTION("with TagListBuilder from pair<const char*, const char*>") { 28 { 29 osmium::builder::TagListBuilder builder(buffer); 30 builder.add_tag(std::pair<const char*, const char*>{"highway", "primary"}); 31 builder.add_tag("name", "Main Street"); 32 } 33 buffer.commit(); 34 } 35 36 SECTION("with TagListBuilder from pair<const char* const, const char*>") { 37 { 38 osmium::builder::TagListBuilder builder(buffer); 39 builder.add_tag(std::pair<const char* const, const char*>{"highway", "primary"}); 40 builder.add_tag("name", "Main Street"); 41 } 42 buffer.commit(); 43 } 44 45 SECTION("with TagListBuilder from pair<const char*, const char* const>") { 46 { 47 osmium::builder::TagListBuilder builder(buffer); 48 builder.add_tag(std::pair<const char*, const char* const>{"highway", "primary"}); 49 builder.add_tag("name", "Main Street"); 50 } 51 buffer.commit(); 52 } 53 54 SECTION("with TagListBuilder from pair<const char* const, const char* const>") { 55 { 56 osmium::builder::TagListBuilder builder(buffer); 57 builder.add_tag(std::pair<const char* const, const char* const>{"highway", "primary"}); 58 builder.add_tag("name", "Main Street"); 59 } 60 buffer.commit(); 61 } 62 63 SECTION("with TagListBuilder from char* with length") { 64 { 65 osmium::builder::TagListBuilder builder(buffer); 66 builder.add_tag("highway", strlen("highway"), "primary", strlen("primary")); 67 builder.add_tag("nameXX", 4, "Main Street", 11); 68 } 69 buffer.commit(); 70 } 71 72 SECTION("with TagListBuilder from std::string") { 73 { 74 osmium::builder::TagListBuilder builder(buffer); 75 builder.add_tag(std::string("highway"), std::string("primary")); 76 const std::string source = "name"; 77 std::string gps = "Main Street"; 78 builder.add_tag(source, gps); 79 } 80 buffer.commit(); 81 } 82 83 SECTION("with add_tag_list from pair<const char*, const char*>") { 84 osmium::builder::add_tag_list(buffer, 85 _tag(std::pair<const char*, const char*>{"highway", "primary"}), 86 _tag("name", "Main Street") 87 ); 88 } 89 90 SECTION("with add_tag_list from pair<const char* const, const char*>") { 91 osmium::builder::add_tag_list(buffer, 92 _tag(std::pair<const char* const, const char*>{"highway", "primary"}), 93 _tag("name", "Main Street") 94 ); 95 } 96 97 SECTION("with add_tag_list from pair<const char*, const char* const>") { 98 osmium::builder::add_tag_list(buffer, 99 _tag(std::pair<const char*, const char* const>{"highway", "primary"}), 100 _tag("name", "Main Street") 101 ); 102 } 103 104 SECTION("with add_tag_list from pair<const char* const, const char* const>") { 105 osmium::builder::add_tag_list(buffer, 106 _tag(std::pair<const char* const, const char* const>{"highway", "primary"}), 107 _tag("name", "Main Street") 108 ); 109 } 110 111 SECTION("with add_tag_list from vector of pairs (const/const)") { 112 std::vector<std::pair<const char* const, const char* const>> v{ 113 { "highway", "primary" }, 114 { "name", "Main Street" } 115 }; 116 osmium::builder::add_tag_list(buffer, _tags(v)); 117 } 118 119 SECTION("with add_tag_list from vector of pairs (const/nc)") { 120 std::vector<std::pair<const char* const, const char*>> v{ 121 { "highway", "primary" }, 122 { "name", "Main Street" } 123 }; 124 osmium::builder::add_tag_list(buffer, _tags(v)); 125 } 126 127 SECTION("with add_tag_list from vector of pairs (nc/const)") { 128 std::vector<std::pair<const char*, const char* const>> v{ 129 { "highway", "primary" }, 130 { "name", "Main Street" } 131 }; 132 osmium::builder::add_tag_list(buffer, _tags(v)); 133 } 134 135 SECTION("with add_tag_list from vector of pairs (nc/nc)") { 136 std::vector<std::pair<const char*, const char*>> v{ 137 { "highway", "primary" }, 138 { "name", "Main Street" } 139 }; 140 osmium::builder::add_tag_list(buffer, _tags(v)); 141 } 142 143 SECTION("with add_tag_list from initializer list") { 144 osmium::builder::add_tag_list(buffer, _tags({ 145 { "highway", "primary" }, 146 { "name", "Main Street" } 147 })); 148 } 149 150 SECTION("with add_tag_list from _tag") { 151 osmium::builder::add_tag_list(buffer, 152 _tag("highway", "primary"), 153 _tag("name", "Main Street") 154 ); 155 } 156 157 SECTION("with add_tag_list from map") { 158 std::map<std::string, std::string> m{ 159 { "highway", "primary" }, 160 { "name", "Main Street" } 161 }; 162 osmium::builder::add_tag_list(buffer, _tags(m)); 163 } 164 165 const osmium::TagList& tl = *buffer.select<osmium::TagList>().cbegin(); 166 REQUIRE(osmium::item_type::tag_list == tl.type()); 167 REQUIRE(2 == tl.size()); 168 169 REQUIRE(tl.has_key("highway")); 170 REQUIRE_FALSE(tl.has_key("unknown")); 171 REQUIRE(tl.has_tag("highway", "primary")); 172 REQUIRE_FALSE(tl.has_tag("highway", "false")); 173 REQUIRE_FALSE(tl.has_tag("foo", "bar")); 174 175 auto it = tl.begin(); 176 REQUIRE(std::string("highway") == it->key()); 177 REQUIRE(std::string("primary") == it->value()); 178 ++it; 179 REQUIRE(std::string("name") == it->key()); 180 REQUIRE(std::string("Main Street") == it->value()); 181 ++it; 182 REQUIRE(it == tl.end()); 183 184 REQUIRE(std::string("primary") == tl.get_value_by_key("highway")); 185 REQUIRE(nullptr == tl.get_value_by_key("foo")); 186 REQUIRE(std::string("default") == tl.get_value_by_key("foo", "default")); 187 188 REQUIRE(std::string("Main Street") == tl["name"]); 189 } 190 191 TEST_CASE("empty keys and values are okay") { 192 osmium::memory::Buffer buffer{10240}; 193 194 const auto pos = osmium::builder::add_tag_list(buffer, 195 _tag("empty value", ""), 196 _tag("", "empty key") 197 ); 198 const osmium::TagList& tl = buffer.get<osmium::TagList>(pos); 199 200 REQUIRE(osmium::item_type::tag_list == tl.type()); 201 REQUIRE(2 == tl.size()); 202 203 auto it = tl.begin(); 204 REQUIRE(std::string("empty value") == it->key()); 205 REQUIRE(std::string("") == it->value()); 206 ++it; 207 REQUIRE(std::string("") == it->key()); 208 REQUIRE(std::string("empty key") == it->value()); 209 ++it; 210 REQUIRE(it == tl.end()); 211 212 REQUIRE(std::string("") == tl.get_value_by_key("empty value")); 213 REQUIRE(std::string("empty key") == tl.get_value_by_key("")); 214 } 215 216 TEST_CASE("tag key or value is too long") { 217 osmium::memory::Buffer buffer{10240}; 218 osmium::builder::TagListBuilder builder{buffer}; 219 220 const char kv[2000] = ""; 221 builder.add_tag(kv, 1, kv, 1000); 222 REQUIRE_THROWS(builder.add_tag(kv, 1500, kv, 1)); 223 REQUIRE_THROWS(builder.add_tag(kv, 1, kv, 1500)); 224 } 225 226