File indexing completed on 2025-01-31 02:19:34
0001 #include "catch.hpp"
0002
0003 #include <iostream>
0004 #include <list>
0005 #include <string>
0006 #include <vector>
0007
0008 #include "FWCore/Utilities/interface/compactStringSerializer.h"
0009 #include "FWCore/Utilities/interface/Exception.h"
0010
0011 namespace cs = edm::compactString;
0012
0013 TEST_CASE("Test edm::compactString serializer", "[edm::compactString]") {
0014 using namespace std::string_literals;
0015 SECTION("Empty inputs") {
0016 SECTION("Serialization") {
0017 SECTION("Empty string") {
0018 auto result = cs::serialize(""s);
0019 CHECK(result.size() == 1);
0020 result = cs::serialize("");
0021 CHECK(result.size() == 1);
0022 }
0023
0024 SECTION("Two empty strings") {
0025 auto result = cs::serialize(""s, ""s);
0026 CHECK(result.size() == 2);
0027 result = cs::serialize(""s, "");
0028 CHECK(result.size() == 2);
0029 result = cs::serialize("", ""s);
0030 CHECK(result.size() == 2);
0031 result = cs::serialize("", "");
0032 CHECK(result.size() == 2);
0033 }
0034
0035 SECTION("Empty vector of strings and empty string") {
0036 auto result = cs::serialize(std::vector<std::string>());
0037 CHECK(result.size() == 1);
0038 result = cs::serialize(""s, std::vector<std::string>());
0039 CHECK(result.size() == 2);
0040 result = cs::serialize(std::vector<std::string>(), "");
0041 CHECK(result.size() == 2);
0042 result = cs::serialize(std::vector<std::string>(), std::vector<std::string>());
0043 CHECK(result.size() == 2);
0044 }
0045
0046 SECTION("Empty list and vector of strings and empty string") {
0047 auto result = cs::serialize(std::list<std::string>());
0048 CHECK(result.size() == 1);
0049 result = cs::serialize(""s, std::list<std::string>());
0050 CHECK(result.size() == 2);
0051 result = cs::serialize(std::list<std::string>(), "");
0052 CHECK(result.size() == 2);
0053 result = cs::serialize(std::list<std::string>(), std::list<std::string>());
0054 CHECK(result.size() == 2);
0055 result = cs::serialize(std::vector<std::string>(), std::list<std::string>());
0056 CHECK(result.size() == 2);
0057 result = cs::serialize(std::list<std::string>(), std::vector<std::string>());
0058 CHECK(result.size() == 2);
0059 }
0060
0061 SECTION("Vectors of empty strings") {
0062 auto result = cs::serialize(std::vector<std::string>{""});
0063 CHECK(result.size() == 2);
0064 result = cs::serialize(std::vector<std::string>{"", ""});
0065 CHECK(result.size() == 3);
0066 result = cs::serialize(std::vector<std::string>{""}, std::vector<std::string>{});
0067 CHECK(result.size() == 3);
0068 result = cs::serialize(std::vector<std::string>{"", ""}, std::vector<std::string>{});
0069 CHECK(result.size() == 4);
0070 result = cs::serialize(std::vector<std::string>{""}, std::vector<std::string>{""});
0071 CHECK(result.size() == 4);
0072 result = cs::serialize(std::vector<std::string>{"", ""}, std::vector<std::string>{""});
0073 CHECK(result.size() == 5);
0074 result = cs::serialize(std::vector<std::string>{""}, std::vector<std::string>{"", ""});
0075 CHECK(result.size() == 5);
0076 result = cs::serialize(std::vector<std::string>{"", ""}, std::vector<std::string>{"", ""});
0077 CHECK(result.size() == 6);
0078 }
0079 }
0080
0081 SECTION("Serialization and deserialization") {
0082 SECTION("Empty string") {
0083 std::string res;
0084 auto ret = cs::deserialize(cs::serialize(""), res);
0085 CHECK(ret == 1);
0086 CHECK(res.empty());
0087 }
0088
0089 SECTION("Two empty strings") {
0090 std::string res1, res2;
0091 auto ret = cs::deserialize(cs::serialize("", ""), res1, res2);
0092 CHECK(ret == 2);
0093 CHECK(res1.empty());
0094 CHECK(res2.empty());
0095 }
0096
0097 SECTION("Empty vector") {
0098 std::vector<std::string> res;
0099 auto ret = cs::deserialize(cs::serialize(std::vector<std::string>()), std::back_inserter(res));
0100 CHECK(ret == 1);
0101 CHECK(res.empty());
0102 }
0103
0104 SECTION("Two empty vectors") {
0105 std::vector<std::string> res1, res2;
0106 auto ret = cs::deserialize(cs::serialize(std::vector<std::string>(), std::vector<std::string>()),
0107 std::back_inserter(res1),
0108 std::back_inserter(res2));
0109 CHECK(ret == 2);
0110 CHECK(res1.empty());
0111 CHECK(res2.empty());
0112 }
0113
0114 SECTION("Mixture") {
0115 std::string res1;
0116 std::vector<std::string> res2;
0117 std::list<std::string> res3;
0118 auto ret = cs::deserialize(cs::serialize("", std::vector<std::string>(), std::list<std::string>()),
0119 res1,
0120 std::back_inserter(res2),
0121 std::back_inserter(res3));
0122 CHECK(ret == 3);
0123 CHECK(res1.empty());
0124 CHECK(res2.empty());
0125 CHECK(res3.empty());
0126
0127 ret = cs::deserialize(cs::serialize(std::vector<std::string>(), "", std::list<std::string>()),
0128 std::back_inserter(res3),
0129 res1,
0130 std::back_inserter(res2));
0131 CHECK(ret == 3);
0132 CHECK(res1.empty());
0133 CHECK(res2.empty());
0134 CHECK(res3.empty());
0135 }
0136 }
0137 }
0138
0139 SECTION("Inputs with values") {
0140 SECTION("Strings") {
0141 std::string res1, res2;
0142 auto serial = cs::serialize("foo");
0143 REQUIRE(serial == "foo"s + cs::detail::kContainerDelimiter);
0144 auto ret = cs::deserialize(serial, res1);
0145 CHECK(ret == 3 + 1);
0146 CHECK(res1 == "foo");
0147
0148 serial = cs::serialize("foo", "bar");
0149 REQUIRE(serial == "foo"s + cs::detail::kContainerDelimiter + "bar"s + cs::detail::kContainerDelimiter);
0150 ret = cs::deserialize(serial, res1, res2);
0151 CHECK(ret == 3 + 1 + 3 + 1);
0152 CHECK(res1 == "foo");
0153 CHECK(res2 == "bar");
0154 }
0155
0156 SECTION("Vector of strings") {
0157 std::vector<std::string> res;
0158 auto serial = cs::serialize(std::vector<std::string>{"foo"});
0159 REQUIRE(serial == "foo"s + cs::detail::kElementDelimiter + cs::detail::kContainerDelimiter);
0160 auto ret = cs::deserialize(serial, std::back_inserter(res));
0161 CHECK(ret == 3 + 2);
0162 REQUIRE(res.size() == 1);
0163 REQUIRE(res[0] == "foo");
0164 res.clear();
0165
0166 serial = cs::serialize(std::vector<std::string>{"foo", "bar"});
0167 REQUIRE(serial == "foo"s + cs::detail::kElementDelimiter + "bar"s + cs::detail::kElementDelimiter +
0168 cs::detail::kContainerDelimiter);
0169 ret = cs::deserialize(serial, std::back_inserter(res));
0170 CHECK(ret == 3 + 1 + 3 + 2);
0171 REQUIRE(res.size() == 2);
0172 CHECK(res[0] == "foo");
0173 CHECK(res[1] == "bar");
0174 res.clear();
0175
0176 serial = cs::serialize(std::vector<std::string>{"foo", "bar", "xyzzy"});
0177 ret = cs::deserialize(serial, std::back_inserter(res));
0178 CHECK(ret == serial.size());
0179 REQUIRE(res.size() == 3);
0180 CHECK(res[0] == "foo");
0181 CHECK(res[1] == "bar");
0182 CHECK(res[2] == "xyzzy");
0183 res.clear();
0184
0185 SECTION("Deserialize to list") {
0186 std::list<std::string> res2;
0187 ret = cs::deserialize(serial, std::front_inserter(res2));
0188 CHECK(ret == serial.size());
0189 REQUIRE(res2.size() == 3);
0190 auto it = res2.begin();
0191 CHECK(*it == "xyzzy");
0192 ++it;
0193 CHECK(*it == "bar");
0194 ++it;
0195 CHECK(*it == "foo");
0196 }
0197 }
0198
0199 SECTION("Vectors of strings") {
0200 std::vector<std::string> res1, res2;
0201 ;
0202 auto serial =
0203 cs::serialize(std::vector<std::string>{"foo", "bar", "xyzzy"}, std::vector<std::string>{"fred", "wilma"});
0204 auto ret = cs::deserialize(serial, std::back_inserter(res1), std::back_inserter(res2));
0205 CHECK(ret == serial.size());
0206 REQUIRE(res1.size() == 3);
0207 CHECK(res1[0] == "foo");
0208 CHECK(res1[1] == "bar");
0209 CHECK(res1[2] == "xyzzy");
0210 REQUIRE(res2.size() == 2);
0211 CHECK(res2[0] == "fred");
0212 CHECK(res2[1] == "wilma");
0213 }
0214
0215 SECTION("Mixture") {
0216 auto serial = cs::serialize(
0217 "foobar", std::vector<std::string>{"fred", "wilma"}, "xyzzy", std::list<std::string>{"one", "two", "th ree"});
0218 std::string res1, res3;
0219 std::vector<std::string> res2, res4;
0220 auto ret = cs::deserialize(serial, res1, std::back_inserter(res2), res3, std::back_inserter(res4));
0221 CHECK(ret == serial.size());
0222 CHECK(res1 == "foobar");
0223 REQUIRE(res2.size() == 2);
0224 CHECK(res2[0] == "fred");
0225 CHECK(res2[1] == "wilma");
0226 CHECK(res3 == "xyzzy");
0227 REQUIRE(res4.size() == 3);
0228 CHECK(res4[0] == "one");
0229 CHECK(res4[1] == "two");
0230 CHECK(res4[2] == "th ree");
0231 }
0232 }
0233 SECTION("Deserialize only part of the serialized content") {
0234 SECTION("String") {
0235 std::string res;
0236 auto serial = cs::serialize("foo", "bar");
0237 auto ret = cs::deserialize(serial, res);
0238 CHECK(ret != 0);
0239 CHECK(ret != serial.size());
0240 CHECK(res == "foo");
0241 res.clear();
0242
0243 serial = cs::serialize("bar", std::vector<std::string>{"foo"});
0244 ret = cs::deserialize(serial, res);
0245 CHECK(ret != 0);
0246 CHECK(ret != serial.size());
0247 CHECK(res == "bar");
0248 }
0249
0250 SECTION("Vector of strings") {
0251 std::vector<std::string> res;
0252 auto serial = cs::serialize(std::vector<std::string>{"foo", "bar"}, std::vector<std::string>{"fred", "wilma"});
0253 auto ret = cs::deserialize(serial, std::back_inserter(res));
0254 CHECK(ret != 0);
0255 CHECK(ret != serial.size());
0256 REQUIRE(res.size() == 2);
0257 CHECK(res[0] == "foo");
0258 CHECK(res[1] == "bar");
0259 res.clear();
0260
0261 serial = cs::serialize(std::vector<std::string>{"wilma", "fred"}, "fintstones");
0262 ret = cs::deserialize(serial, std::back_inserter(res));
0263 CHECK(ret != 0);
0264 CHECK(ret != serial.size());
0265 REQUIRE(res.size() == 2);
0266 CHECK(res[0] == "wilma");
0267 CHECK(res[1] == "fred");
0268 }
0269 }
0270
0271 SECTION("Serialization error cases") {
0272 CHECK_THROWS_AS(cs::serialize(""s + cs::detail::kElementDelimiter), cms::Exception);
0273 CHECK_THROWS_AS(cs::serialize("foo"s + cs::detail::kElementDelimiter), cms::Exception);
0274 CHECK_THROWS_AS(cs::serialize(cs::detail::kElementDelimiter + "bar"s), cms::Exception);
0275 CHECK_THROWS_AS(cs::serialize("foo"s + cs::detail::kElementDelimiter + "bar"s), cms::Exception);
0276 CHECK_THROWS_AS(cs::serialize(""s + cs::detail::kContainerDelimiter), cms::Exception);
0277 CHECK_THROWS_AS(cs::serialize("foo"s + cs::detail::kContainerDelimiter), cms::Exception);
0278 CHECK_THROWS_AS(cs::serialize(cs::detail::kContainerDelimiter + "bar"s), cms::Exception);
0279 CHECK_THROWS_AS(cs::serialize("foo"s + cs::detail::kContainerDelimiter + "bar"s), cms::Exception);
0280
0281 std::string str = "foo"s + cs::detail::kContainerDelimiter;
0282 std::vector<std::string> vstr{str};
0283 CHECK_THROWS_AS(cs::serialize(str, std::vector<std::string>{"foo"}), cms::Exception);
0284 CHECK_THROWS_AS(cs::serialize(std::vector<std::string>{"foo"}, str), cms::Exception);
0285 CHECK_THROWS_AS(cs::serialize(vstr, "foo"), cms::Exception);
0286 CHECK_THROWS_AS(cs::serialize("foo", vstr), cms::Exception);
0287 }
0288
0289 SECTION("Deserialization error cases") {
0290 SECTION("Invalid input") {
0291 SECTION("Deserializing to string") {
0292 std::string res;
0293 CHECK(cs::deserialize("", res) == 0);
0294 CHECK(cs::deserialize(" ", res) == 0);
0295 CHECK(cs::deserialize("foo", res) == 0);
0296 CHECK(cs::deserialize("foo"s + cs::detail::kElementDelimiter + "bar"s, res) == 0);
0297 CHECK(cs::deserialize("foo"s + cs::detail::kElementDelimiter + "bar"s + cs::detail::kContainerDelimiter, res) ==
0298 0);
0299 }
0300
0301 SECTION("Deserializing to container") {
0302 std::vector<std::string> res;
0303 CHECK(cs::deserialize("", std::back_inserter(res)) == 0);
0304 CHECK(cs::deserialize(" ", std::back_inserter(res)) == 0);
0305 CHECK(cs::deserialize("foo", std::back_inserter(res)) == 0);
0306 CHECK(cs::deserialize("foo"s + cs::detail::kElementDelimiter + "bar"s, std::back_inserter(res)) == 0);
0307 CHECK(cs::deserialize("foo"s + cs::detail::kContainerDelimiter, std::back_inserter(res)) == 0);
0308 }
0309 }
0310
0311 SECTION("Schema mismatch") {
0312
0313
0314
0315
0316 SECTION("Deserializing container as string") {
0317 std::string res;
0318 auto ret = cs::deserialize(cs::serialize(std::vector<std::string>{""}), res);
0319 CHECK(ret == 0);
0320 ret = cs::deserialize(cs::serialize(std::vector<std::string>{"foo"}), res);
0321 CHECK(ret == 0);
0322 ret = cs::deserialize(cs::serialize(std::vector<std::string>{"foo", "bar"}), res);
0323 CHECK(ret == 0);
0324 }
0325
0326 SECTION("Deserializing string as container") {
0327 std::vector<std::string> res;
0328 auto ret = cs::deserialize(cs::serialize("foo"), std::back_inserter(res));
0329 CHECK(ret == 0);
0330 ret = cs::deserialize(cs::serialize("foo", "bar"), std::back_inserter(res));
0331 CHECK(ret == 0);
0332 }
0333 }
0334
0335 SECTION("Deserializing too much") {
0336 SECTION("Strings") {
0337 std::string res1, res2;
0338 auto ret = cs::deserialize(cs::serialize("foo"), res1, res2);
0339 CHECK(ret == 0);
0340 CHECK(res2.empty());
0341 }
0342
0343 SECTION("Vector of strings") {
0344 std::vector<std::string> res1, res2;
0345 auto ret = cs::deserialize(
0346 cs::serialize(std::vector<std::string>{"foo", "bar"}), std::back_inserter(res1), std::back_inserter(res2));
0347 CHECK(ret == 0);
0348 CHECK(res2.empty());
0349 }
0350
0351 SECTION("Mixture") {
0352 std::string ress;
0353 std::vector<std::string> resv;
0354 auto ret = cs::deserialize(cs::serialize("foo"), ress, std::back_inserter(resv));
0355 CHECK(ret == 0);
0356 CHECK(resv.empty());
0357 ress.clear();
0358
0359 ret = cs::deserialize(cs::serialize(std::vector<std::string>{"foo"}), std::back_inserter(resv), ress);
0360 CHECK(ret == 0);
0361 CHECK(ress.empty());
0362 }
0363 }
0364 }
0365 }