mirror of
https://github.com/transmission/transmission
synced 2024-12-21 23:32:35 +00:00
test: use new tr_variant
API (#7268)
* test: new `tr_variant` API in `json-test.cc` * test: new `tr_variant` API in `variant-test.cc` * chore: housekeeping * test: new `tr_variant` API in `dht-test.cc` * fix: use `reinterpret_cast` in `tr_variant::make_raw()` * fix: add missing `typename` in `tr_variant::make_raw()` * test: new `tr_variant` API in `settings-test.cc` * test: new `tr_variant` API in `move-test.cc` * test: new `tr_variant` API in `rpc-test.cc` * test: new `tr_variant` API in `makemeta-test.cc` * test: new `tr_variant` API in `session-test.cc`
This commit is contained in:
parent
510286f419
commit
90859fe115
10 changed files with 515 additions and 483 deletions
|
@ -219,13 +219,13 @@ public:
|
|||
|
||||
[[nodiscard]] static auto make_raw(void const* value, size_t n_bytes)
|
||||
{
|
||||
return tr_variant{ std::string{ static_cast<char const*>(value), n_bytes } };
|
||||
return tr_variant{ std::string_view{ reinterpret_cast<char const*>(value), n_bytes } };
|
||||
}
|
||||
|
||||
template<typename CharSpan>
|
||||
[[nodiscard]] static auto make_raw(CharSpan const& value)
|
||||
{
|
||||
static_assert(sizeof(CharSpan::value_type) == 1U);
|
||||
static_assert(sizeof(typename CharSpan::value_type) == 1U);
|
||||
return make_raw(std::data(value), std::size(value));
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <libtransmission/tr-macros.h>
|
||||
#include <libtransmission/tr-strbuf.h>
|
||||
#include <libtransmission/utils.h>
|
||||
#include <libtransmission/variant.h> // tr_variantDictAddRaw
|
||||
#include <libtransmission/variant.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "test-fixtures.h"
|
||||
|
@ -126,23 +126,22 @@ protected:
|
|||
{
|
||||
auto const dat_file = MockStateFile::filename(path);
|
||||
|
||||
auto dict = tr_variant{};
|
||||
tr_variantInitDict(&dict, 3U);
|
||||
tr_variantDictAddRaw(&dict, TR_KEY_id, std::data(id_), std::size(id_));
|
||||
tr_variantDictAddInt(&dict, TR_KEY_id_timestamp, id_timestamp_);
|
||||
auto map = tr_variant::Map{ 3U };
|
||||
map.try_emplace(TR_KEY_id, tr_variant::make_raw(id_));
|
||||
map.try_emplace(TR_KEY_id_timestamp, id_timestamp_);
|
||||
auto compact = std::vector<std::byte>{};
|
||||
for (auto const& socket_address : ipv4_nodes_)
|
||||
{
|
||||
socket_address.to_compact(std::back_inserter(compact));
|
||||
}
|
||||
tr_variantDictAddRaw(&dict, TR_KEY_nodes, std::data(compact), std::size(compact));
|
||||
map.try_emplace(TR_KEY_nodes, tr_variant::make_raw(compact));
|
||||
compact.clear();
|
||||
for (auto const& socket_address : ipv6_nodes_)
|
||||
{
|
||||
socket_address.to_compact(std::back_inserter(compact));
|
||||
}
|
||||
tr_variantDictAddRaw(&dict, TR_KEY_nodes6, std::data(compact), std::size(compact));
|
||||
tr_variant_serde::benc().to_file(dict, dat_file);
|
||||
map.try_emplace(TR_KEY_nodes6, tr_variant::make_raw(compact));
|
||||
tr_variant_serde::benc().to_file(tr_variant{ std::move(map) }, dat_file);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ private:
|
|||
|
||||
TEST_P(JSONTest, testElements)
|
||||
{
|
||||
auto const in = std::string{
|
||||
static auto constexpr In = std::string_view{
|
||||
"{ \"string\": \"hello world\","
|
||||
" \"escaped\": \"bell \\b formfeed \\f linefeed \\n carriage return \\r tab \\t\","
|
||||
" \"int\": 5, "
|
||||
|
@ -61,54 +61,60 @@ TEST_P(JSONTest, testElements)
|
|||
" \"null\": null }"
|
||||
};
|
||||
|
||||
auto var = tr_variant_serde::json().inplace().parse(in).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
auto const var = tr_variant_serde::json().inplace().parse(In).value_or(tr_variant{});
|
||||
auto const* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
|
||||
auto sv = std::string_view{};
|
||||
auto key = tr_quark_new("string"sv);
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("hello world"sv, sv);
|
||||
auto sv = map->value_if<std::string_view>(tr_quark_new("string"sv));
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("hello world"sv, *sv);
|
||||
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, tr_quark_new("escaped"sv), &sv));
|
||||
EXPECT_EQ("bell \b formfeed \f linefeed \n carriage return \r tab \t"sv, sv);
|
||||
sv = map->value_if<std::string_view>(tr_quark_new("escaped"sv));
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("bell \b formfeed \f linefeed \n carriage return \r tab \t"sv, *sv);
|
||||
|
||||
auto i = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, tr_quark_new("int"sv), &i));
|
||||
EXPECT_EQ(5, i);
|
||||
auto i = map->value_if<int64_t>(tr_quark_new("int"sv));
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(5, *i);
|
||||
|
||||
auto d = double{};
|
||||
EXPECT_TRUE(tr_variantDictFindReal(&var, tr_quark_new("float"sv), &d));
|
||||
EXPECT_EQ(65, int(d * 10));
|
||||
auto d = map->value_if<double>(tr_quark_new("float"sv));
|
||||
ASSERT_TRUE(d);
|
||||
EXPECT_EQ(65, int(*d * 10));
|
||||
|
||||
auto f = bool{};
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&var, tr_quark_new("true"sv), &f));
|
||||
EXPECT_TRUE(f);
|
||||
auto b = map->value_if<bool>(tr_quark_new("true"sv));
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_TRUE(*b);
|
||||
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&var, tr_quark_new("false"sv), &f));
|
||||
EXPECT_FALSE(f);
|
||||
b = map->value_if<bool>(tr_quark_new("false"sv));
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_FALSE(*b);
|
||||
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, tr_quark_new("null"sv), &sv));
|
||||
EXPECT_EQ(""sv, sv);
|
||||
sv = map->value_if<std::string_view>(tr_quark_new("null"sv));
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ(""sv, *sv);
|
||||
}
|
||||
|
||||
TEST_P(JSONTest, testUtf8)
|
||||
{
|
||||
auto in = "{ \"key\": \"Letöltések\" }"sv;
|
||||
auto sv = std::string_view{};
|
||||
tr_quark const key = tr_quark_new("key"sv);
|
||||
|
||||
auto serde = tr_variant_serde::json().inplace().compact();
|
||||
auto var = serde.parse(in).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("Letöltések"sv, sv);
|
||||
auto* map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto sv = map->value_if<std::string_view>(key);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("Letöltések"sv, *sv);
|
||||
var.clear();
|
||||
|
||||
in = R"({ "key": "\u005C" })"sv;
|
||||
var = serde.parse(in).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("\\"sv, sv);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
sv = map->value_if<std::string_view>(key);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("\\"sv, *sv);
|
||||
var.clear();
|
||||
|
||||
/**
|
||||
|
@ -121,41 +127,51 @@ TEST_P(JSONTest, testUtf8)
|
|||
*/
|
||||
in = R"({ "key": "Let\u00f6lt\u00e9sek" })"sv;
|
||||
var = serde.parse(in).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("Letöltések"sv, sv);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
sv = map->value_if<std::string_view>(key);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("Letöltések"sv, *sv);
|
||||
auto json = serde.to_string(var);
|
||||
var.clear();
|
||||
|
||||
EXPECT_FALSE(std::empty(json));
|
||||
EXPECT_EQ(R"({"key":"Letöltések"})"sv, json);
|
||||
var = serde.parse(json).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("Letöltések"sv, sv);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
sv = map->value_if<std::string_view>(key);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("Letöltések"sv, *sv);
|
||||
|
||||
// Test string known to be prone to locale issues
|
||||
// https://github.com/transmission/transmission/issues/5967
|
||||
var.clear();
|
||||
tr_variantInitDict(&var, 1U);
|
||||
tr_variantDictAddStr(&var, key, "Дыскаграфія"sv);
|
||||
var = tr_variant::make_map(1U);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
map->try_emplace(key, "Дыскаграфія"sv);
|
||||
json = serde.to_string(var);
|
||||
EXPECT_EQ(R"({"key":"Дыскаграфія"})"sv, json);
|
||||
var = serde.parse(json).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("Дыскаграфія"sv, sv);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
sv = map->value_if<std::string_view>(key);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("Дыскаграфія"sv, *sv);
|
||||
|
||||
// Thinking emoji 🤔
|
||||
var.clear();
|
||||
tr_variantInitDict(&var, 1U);
|
||||
tr_variantDictAddStr(&var, key, "\xf0\x9f\xa4\x94"sv);
|
||||
var = tr_variant::make_map(1U);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
map->try_emplace(key, "\xf0\x9f\xa4\x94"sv);
|
||||
json = serde.to_string(var);
|
||||
EXPECT_EQ("{\"key\":\"\xf0\x9f\xa4\x94\"}"sv, json);
|
||||
var = serde.parse(json).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, key, &sv));
|
||||
EXPECT_EQ("\xf0\x9f\xa4\x94"sv, sv);
|
||||
map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
sv = map->value_if<std::string_view>(key);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("\xf0\x9f\xa4\x94"sv, *sv);
|
||||
}
|
||||
|
||||
TEST_P(JSONTest, test1)
|
||||
|
@ -176,32 +192,33 @@ TEST_P(JSONTest, test1)
|
|||
|
||||
auto serde = tr_variant_serde::json();
|
||||
auto var = serde.inplace().parse(Input).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
auto* map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
|
||||
auto sv = std::string_view{};
|
||||
auto i = int64_t{};
|
||||
auto* headers = tr_variantDictFind(&var, tr_quark_new("headers"sv));
|
||||
EXPECT_NE(nullptr, headers);
|
||||
EXPECT_TRUE(headers->holds_alternative<tr_variant::Map>());
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(headers, tr_quark_new("type"sv), &sv));
|
||||
EXPECT_EQ("request"sv, sv);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(headers, TR_KEY_tag, &i));
|
||||
EXPECT_EQ(666, i);
|
||||
auto* body = tr_variantDictFind(&var, tr_quark_new("body"sv));
|
||||
EXPECT_NE(nullptr, body);
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(body, TR_KEY_name, &sv));
|
||||
EXPECT_EQ("torrent-info"sv, sv);
|
||||
auto* args = tr_variantDictFind(body, tr_quark_new("arguments"sv));
|
||||
EXPECT_NE(nullptr, args);
|
||||
EXPECT_TRUE(args->holds_alternative<tr_variant::Map>());
|
||||
auto* ids = tr_variantDictFind(args, TR_KEY_ids);
|
||||
ASSERT_NE(nullptr, ids);
|
||||
EXPECT_TRUE(ids->holds_alternative<tr_variant::Vector>());
|
||||
EXPECT_EQ(2U, tr_variantListSize(ids));
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(ids, 0), &i));
|
||||
EXPECT_EQ(7, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(ids, 1), &i));
|
||||
EXPECT_EQ(10, i);
|
||||
auto* headers = map->find_if<tr_variant::Map>(tr_quark_new("headers"sv));
|
||||
ASSERT_NE(headers, nullptr);
|
||||
auto sv = headers->value_if<std::string_view>(tr_quark_new("type"sv));
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("request"sv, *sv);
|
||||
auto i = headers->value_if<int64_t>(TR_KEY_tag);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(666, *i);
|
||||
auto* body = map->find_if<tr_variant::Map>(tr_quark_new("body"sv));
|
||||
ASSERT_NE(body, nullptr);
|
||||
sv = body->value_if<std::string_view>(TR_KEY_name);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("torrent-info"sv, *sv);
|
||||
auto* args = body->find_if<tr_variant::Map>(tr_quark_new("arguments"sv));
|
||||
ASSERT_NE(args, nullptr);
|
||||
auto* ids = args->find_if<tr_variant::Vector>(TR_KEY_ids);
|
||||
ASSERT_NE(ids, nullptr);
|
||||
EXPECT_EQ(2U, std::size(*ids));
|
||||
i = (*ids)[0].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(7, *i);
|
||||
i = (*ids)[1].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(10, *i);
|
||||
}
|
||||
|
||||
TEST_P(JSONTest, test2)
|
||||
|
@ -221,11 +238,12 @@ TEST_P(JSONTest, test3)
|
|||
" \"leftUntilDone\": 2275655680 }"sv;
|
||||
|
||||
auto var = tr_variant_serde::json().inplace().parse(Input).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
auto* map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
|
||||
auto sv = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, TR_KEY_errorString, &sv));
|
||||
EXPECT_EQ("torrent not registered with this tracker 6UHsVW'*C"sv, sv);
|
||||
auto sv = map->value_if<std::string_view>(TR_KEY_errorString);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("torrent not registered with this tracker 6UHsVW'*C"sv, *sv);
|
||||
}
|
||||
|
||||
TEST_P(JSONTest, unescape)
|
||||
|
@ -233,11 +251,12 @@ TEST_P(JSONTest, unescape)
|
|||
static auto constexpr Input = R"({ "string-1": "\/usr\/lib" })"sv;
|
||||
|
||||
auto var = tr_variant_serde::json().inplace().parse(Input).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Map>());
|
||||
auto* map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
|
||||
auto sv = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, tr_quark_new("string-1"sv), &sv));
|
||||
EXPECT_EQ("/usr/lib"sv, sv);
|
||||
auto sv = map->value_if<std::string_view>(tr_quark_new("string-1"sv));
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("/usr/lib"sv, *sv);
|
||||
}
|
||||
|
||||
TEST_P(JSONTest, parseJsonFuzz)
|
||||
|
|
|
@ -239,15 +239,16 @@ TEST_F(MakemetaTest, announceSingleTracker)
|
|||
// generate the torrent and parse it as a variant
|
||||
EXPECT_FALSE(builder.make_checksums().get().has_value());
|
||||
auto top = tr_variant_serde::benc().parse(builder.benc());
|
||||
EXPECT_TRUE(top.has_value());
|
||||
ASSERT_TRUE(top);
|
||||
auto* map = top->get_if<tr_variant::Map>();
|
||||
|
||||
// confirm there's an "announce" entry
|
||||
auto single_announce = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&*top, TR_KEY_announce, &single_announce));
|
||||
EXPECT_EQ(SingleAnnounce, single_announce);
|
||||
auto single_announce = map->value_if<std::string_view>(TR_KEY_announce);
|
||||
ASSERT_TRUE(single_announce);
|
||||
EXPECT_EQ(SingleAnnounce, *single_announce);
|
||||
|
||||
// confirm there's not an "announce-list" entry
|
||||
EXPECT_EQ(nullptr, tr_variantDictFind(&*top, TR_KEY_announce_list));
|
||||
EXPECT_EQ(map->find(TR_KEY_announce_list), std::end(*map));
|
||||
}
|
||||
|
||||
TEST_F(MakemetaTest, announceMultiTracker)
|
||||
|
@ -267,18 +268,18 @@ TEST_F(MakemetaTest, announceMultiTracker)
|
|||
// generate the torrent and parse it as a variant
|
||||
EXPECT_FALSE(builder.make_checksums().get().has_value());
|
||||
auto top = tr_variant_serde::benc().parse(builder.benc());
|
||||
EXPECT_TRUE(top.has_value());
|
||||
ASSERT_TRUE(top);
|
||||
auto* map = top->get_if<tr_variant::Map>();
|
||||
|
||||
// confirm there's an "announce" entry
|
||||
auto single_announce = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&*top, TR_KEY_announce, &single_announce));
|
||||
EXPECT_EQ(builder.announce_list().at(0).announce.sv(), single_announce);
|
||||
auto single_announce = map->value_if<std::string_view>(TR_KEY_announce);
|
||||
ASSERT_TRUE(single_announce);
|
||||
EXPECT_EQ(builder.announce_list().at(0).announce.sv(), *single_announce);
|
||||
|
||||
// confirm there's an "announce-list" entry
|
||||
tr_variant* announce_list_variant = nullptr;
|
||||
EXPECT_TRUE(tr_variantDictFindList(&*top, TR_KEY_announce_list, &announce_list_variant));
|
||||
EXPECT_NE(nullptr, announce_list_variant);
|
||||
EXPECT_EQ(std::size(builder.announce_list()), tr_variantListSize(announce_list_variant));
|
||||
auto* announce_list_variant = map->find_if<tr_variant::Vector>(TR_KEY_announce_list);
|
||||
ASSERT_NE(announce_list_variant, nullptr);
|
||||
EXPECT_EQ(std::size(builder.announce_list()), std::size(*announce_list_variant));
|
||||
}
|
||||
|
||||
TEST_F(MakemetaTest, privateAndSourceHasDifferentInfoHash)
|
||||
|
|
|
@ -37,11 +37,14 @@ class IncompleteDirTest
|
|||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
auto const download_dir = GetParam().second;
|
||||
tr_variantDictAddStr(settings(), TR_KEY_download_dir, download_dir);
|
||||
auto const incomplete_dir = GetParam().first;
|
||||
tr_variantDictAddStr(settings(), TR_KEY_incomplete_dir, incomplete_dir);
|
||||
tr_variantDictAddBool(settings(), TR_KEY_incomplete_dir_enabled, true);
|
||||
if (auto* map = settings()->get_if<tr_variant::Map>(); map != nullptr)
|
||||
{
|
||||
auto const download_dir = GetParam().second;
|
||||
map->insert_or_assign(TR_KEY_download_dir, download_dir);
|
||||
auto const incomplete_dir = GetParam().first;
|
||||
map->insert_or_assign(TR_KEY_incomplete_dir, incomplete_dir);
|
||||
map->insert_or_assign(TR_KEY_incomplete_dir_enabled, true);
|
||||
}
|
||||
|
||||
SessionTest::SetUp();
|
||||
}
|
||||
|
|
|
@ -32,38 +32,43 @@ using RpcTest = SessionTest;
|
|||
|
||||
TEST_F(RpcTest, list)
|
||||
{
|
||||
auto i = int64_t{};
|
||||
auto sv = std::string_view{};
|
||||
|
||||
auto top = tr_rpc_parse_list_str("12"sv);
|
||||
EXPECT_TRUE(top.holds_alternative<int64_t>());
|
||||
EXPECT_TRUE(tr_variantGetInt(&top, &i));
|
||||
EXPECT_EQ(12, i);
|
||||
auto i = top.value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(12, *i);
|
||||
|
||||
top = tr_rpc_parse_list_str("6,7"sv);
|
||||
EXPECT_TRUE(top.holds_alternative<tr_variant::Vector>());
|
||||
EXPECT_EQ(2U, tr_variantListSize(&top));
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&top, 0), &i));
|
||||
EXPECT_EQ(6, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&top, 1), &i));
|
||||
EXPECT_EQ(7, i);
|
||||
auto* v = top.get_if<tr_variant::Vector>();
|
||||
ASSERT_NE(v, nullptr);
|
||||
EXPECT_EQ(2U, std::size(*v));
|
||||
i = (*v)[0].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(6, *i);
|
||||
i = (*v)[1].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(7, *i);
|
||||
|
||||
top = tr_rpc_parse_list_str("asdf"sv);
|
||||
EXPECT_TRUE(top.holds_alternative<std::string_view>());
|
||||
EXPECT_TRUE(tr_variantGetStrView(&top, &sv));
|
||||
EXPECT_EQ("asdf"sv, sv);
|
||||
auto sv = top.value_if<std::string_view>();
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("asdf"sv, *sv);
|
||||
|
||||
top = tr_rpc_parse_list_str("1,3-5"sv);
|
||||
EXPECT_TRUE(top.holds_alternative<tr_variant::Vector>());
|
||||
EXPECT_EQ(4U, tr_variantListSize(&top));
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&top, 0), &i));
|
||||
EXPECT_EQ(1, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&top, 1), &i));
|
||||
EXPECT_EQ(3, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&top, 2), &i));
|
||||
EXPECT_EQ(4, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&top, 3), &i));
|
||||
EXPECT_EQ(5, i);
|
||||
v = top.get_if<tr_variant::Vector>();
|
||||
ASSERT_NE(v, nullptr);
|
||||
EXPECT_EQ(4U, std::size(*v));
|
||||
i = (*v)[0].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(1, *i);
|
||||
i = (*v)[1].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(3, *i);
|
||||
i = (*v)[2].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(4, *i);
|
||||
i = (*v)[3].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(5, *i);
|
||||
}
|
||||
|
||||
TEST_F(RpcTest, tagSync)
|
||||
|
@ -154,18 +159,18 @@ TEST_F(RpcTest, sessionGet)
|
|||
auto* tor = zeroTorrentInit(ZeroTorrentState::NoFiles);
|
||||
EXPECT_NE(nullptr, tor);
|
||||
|
||||
auto request = tr_variant{};
|
||||
tr_variantInitDict(&request, 1);
|
||||
tr_variantDictAddStrView(&request, TR_KEY_method, "session-get");
|
||||
auto request_map = tr_variant::Map{ 1U };
|
||||
request_map.try_emplace(TR_KEY_method, "session-get"sv);
|
||||
auto response = tr_variant{};
|
||||
tr_rpc_request_exec(
|
||||
session_,
|
||||
request,
|
||||
std::move(request_map),
|
||||
[&response](tr_session* /*session*/, tr_variant&& resp) { response = std::move(resp); });
|
||||
|
||||
EXPECT_TRUE(response.holds_alternative<tr_variant::Map>());
|
||||
tr_variant* args = nullptr;
|
||||
EXPECT_TRUE(tr_variantDictFindDict(&response, TR_KEY_arguments, &args));
|
||||
auto* response_map = response.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(response_map, nullptr);
|
||||
auto* args_map = response_map->find_if<tr_variant::Map>(TR_KEY_arguments);
|
||||
ASSERT_NE(args_map, nullptr);
|
||||
|
||||
// what we expected
|
||||
static auto constexpr ExpectedKeys = std::array{
|
||||
|
@ -233,10 +238,7 @@ TEST_F(RpcTest, sessionGet)
|
|||
|
||||
// what we got
|
||||
std::set<tr_quark> actual_keys;
|
||||
auto key = tr_quark{};
|
||||
tr_variant* val = nullptr;
|
||||
auto n = size_t{};
|
||||
while ((tr_variantDictChild(args, n++, &key, &val)))
|
||||
for (auto const& [key, val] : *args_map)
|
||||
{
|
||||
actual_keys.insert(key);
|
||||
}
|
||||
|
@ -268,35 +270,36 @@ TEST_F(RpcTest, torrentGet)
|
|||
auto* tor = zeroTorrentInit(ZeroTorrentState::NoFiles);
|
||||
EXPECT_NE(nullptr, tor);
|
||||
|
||||
tr_variant request;
|
||||
tr_variantInitDict(&request, 1);
|
||||
auto request = tr_variant::Map{ 1U };
|
||||
|
||||
tr_variantDictAddStrView(&request, TR_KEY_method, "torrent-get");
|
||||
request.try_emplace(TR_KEY_method, "torrent-get");
|
||||
|
||||
tr_variant* args_in = tr_variantDictAddDict(&request, TR_KEY_arguments, 1);
|
||||
tr_variant* fields = tr_variantDictAddList(args_in, TR_KEY_fields, 1);
|
||||
tr_variantListAddStrView(fields, tr_quark_get_string_view(TR_KEY_id));
|
||||
auto args_in = tr_variant::Map{ 1U };
|
||||
auto fields = tr_variant::Vector{};
|
||||
fields.emplace_back(tr_quark_get_string_view(TR_KEY_id));
|
||||
args_in.try_emplace(TR_KEY_fields, std::move(fields));
|
||||
request.try_emplace(TR_KEY_arguments, std::move(args_in));
|
||||
|
||||
auto response = tr_variant{};
|
||||
tr_rpc_request_exec(
|
||||
session_,
|
||||
request,
|
||||
std::move(request),
|
||||
[&response](tr_session* /*session*/, tr_variant&& resp) { response = std::move(resp); });
|
||||
|
||||
EXPECT_TRUE(response.holds_alternative<tr_variant::Map>());
|
||||
tr_variant* args = nullptr;
|
||||
EXPECT_TRUE(tr_variantDictFindDict(&response, TR_KEY_arguments, &args));
|
||||
auto* response_map = response.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(response_map, nullptr);
|
||||
auto* args_out = response_map->find_if<tr_variant::Map>(TR_KEY_arguments);
|
||||
ASSERT_NE(args_out, nullptr);
|
||||
|
||||
tr_variant* torrents = nullptr;
|
||||
EXPECT_TRUE(tr_variantDictFindList(args, TR_KEY_torrents, &torrents));
|
||||
EXPECT_EQ(1UL, tr_variantListSize(torrents));
|
||||
auto* torrents = args_out->find_if<tr_variant::Vector>(TR_KEY_torrents);
|
||||
ASSERT_NE(torrents, nullptr);
|
||||
EXPECT_EQ(1UL, std::size(*torrents));
|
||||
|
||||
tr_variant* first_torrent = tr_variantListChild(torrents, 0);
|
||||
EXPECT_TRUE(first_torrent != nullptr);
|
||||
EXPECT_TRUE(first_torrent->holds_alternative<tr_variant::Map>());
|
||||
int64_t first_torrent_id = 0;
|
||||
EXPECT_TRUE(tr_variantDictFindInt(first_torrent, TR_KEY_id, &first_torrent_id));
|
||||
EXPECT_EQ(1, first_torrent_id);
|
||||
auto* first_torrent = (*torrents)[0].get_if<tr_variant::Map>();
|
||||
ASSERT_NE(first_torrent, nullptr);
|
||||
auto first_torrent_id = first_torrent->value_if<int64_t>(TR_KEY_id);
|
||||
ASSERT_TRUE(first_torrent_id);
|
||||
EXPECT_EQ(1, *first_torrent_id);
|
||||
|
||||
// cleanup
|
||||
tr_torrentRemove(tor, false, nullptr, nullptr, nullptr, nullptr);
|
||||
|
|
|
@ -283,14 +283,16 @@ TEST_F(SessionTest, sessionId)
|
|||
TEST_F(SessionTest, getDefaultSettingsIncludesSubmodules)
|
||||
{
|
||||
auto settings = tr_sessionGetDefaultSettings();
|
||||
auto* settings_map = settings.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(settings_map, nullptr);
|
||||
|
||||
// Choose a setting from each of [tr_session, tr_session_alt_speeds, tr_rpc_server] to test all of them.
|
||||
// These are all `false` by default
|
||||
for (auto const& key : { TR_KEY_peer_port_random_on_start, TR_KEY_alt_speed_time_enabled, TR_KEY_rpc_enabled })
|
||||
{
|
||||
auto flag = bool{};
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&settings, key, &flag));
|
||||
EXPECT_FALSE(flag);
|
||||
auto flag = settings_map->value_if<bool>(key);
|
||||
ASSERT_TRUE(flag);
|
||||
EXPECT_FALSE(*flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,10 +306,11 @@ TEST_F(SessionTest, honorsSettings)
|
|||
// Choose a setting from each of [tr_session, tr_session_alt_speeds, tr_rpc_server] to test all of them.
|
||||
// These are all `false` by default
|
||||
auto settings = tr_sessionGetDefaultSettings();
|
||||
auto* settings_map = settings.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(settings_map, nullptr);
|
||||
for (auto const& key : { TR_KEY_peer_port_random_on_start, TR_KEY_alt_speed_time_enabled, TR_KEY_rpc_enabled })
|
||||
{
|
||||
tr_variantDictRemove(&settings, key);
|
||||
tr_variantDictAddBool(&settings, key, true);
|
||||
settings_map->insert_or_assign(key, true);
|
||||
}
|
||||
auto* session = tr_sessionInit(sandboxDir().data(), false, settings);
|
||||
|
||||
|
@ -332,11 +335,13 @@ TEST_F(SessionTest, savesSettings)
|
|||
|
||||
// Choose a setting from each of [tr_session, tr_session_alt_speeds, tr_rpc_server] to test all of them.
|
||||
auto settings = tr_sessionGetSettings(session_);
|
||||
auto* settings_map = settings.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(settings_map, nullptr);
|
||||
for (auto const& key : { TR_KEY_peer_port_random_on_start, TR_KEY_alt_speed_time_enabled, TR_KEY_rpc_enabled })
|
||||
{
|
||||
auto flag = bool{};
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&settings, key, &flag));
|
||||
EXPECT_TRUE(flag);
|
||||
auto flag = settings_map->value_if<bool>(key);
|
||||
ASSERT_TRUE(flag);
|
||||
EXPECT_TRUE(*flag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,9 @@ TEST_F(SettingsTest, canLoadBools)
|
|||
auto settings = tr_session::Settings{};
|
||||
auto const expected_value = !settings.seed_queue_enabled;
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddBool(&var, Key, expected_value);
|
||||
settings.load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, expected_value);
|
||||
settings.load(tr_variant{ std::move(map) });
|
||||
|
||||
EXPECT_EQ(expected_value, settings.seed_queue_enabled);
|
||||
}
|
||||
|
@ -56,9 +55,11 @@ TEST_F(SettingsTest, canSaveBools)
|
|||
settings.seed_queue_enabled = expected_value;
|
||||
|
||||
auto var = settings.save();
|
||||
auto val = bool{};
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&var, Key, &val));
|
||||
EXPECT_EQ(expected_value, val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<bool>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(expected_value, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadDoubles)
|
||||
|
@ -68,10 +69,9 @@ TEST_F(SettingsTest, canLoadDoubles)
|
|||
auto settings = tr_session::Settings{};
|
||||
auto const expected_value = settings.ratio_limit + 1.0;
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddReal(&var, Key, expected_value);
|
||||
settings.load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, expected_value);
|
||||
settings.load(tr_variant{ std::move(map) });
|
||||
EXPECT_NEAR(expected_value, settings.ratio_limit, 0.001);
|
||||
}
|
||||
|
||||
|
@ -85,9 +85,11 @@ TEST_F(SettingsTest, canSaveDoubles)
|
|||
settings.seed_queue_enabled = expected_value;
|
||||
|
||||
auto var = settings.save();
|
||||
auto val = bool{};
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&var, Key, &val));
|
||||
EXPECT_EQ(expected_value, val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<bool>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(expected_value, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadEncryptionMode)
|
||||
|
@ -98,17 +100,15 @@ TEST_F(SettingsTest, canLoadEncryptionMode)
|
|||
auto settings = std::make_unique<tr_session::Settings>();
|
||||
ASSERT_NE(ExpectedValue, settings->encryption_mode);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue);
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ExpectedValue);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->encryption_mode);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "required");
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "required"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->encryption_mode);
|
||||
}
|
||||
|
||||
|
@ -122,9 +122,11 @@ TEST_F(SettingsTest, canSaveEncryptionMode)
|
|||
settings.encryption_mode = ExpectedValue;
|
||||
|
||||
auto var = settings.save();
|
||||
auto val = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val));
|
||||
EXPECT_EQ(ExpectedValue, val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<int64_t>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(ExpectedValue, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadLogLevel)
|
||||
|
@ -136,17 +138,15 @@ TEST_F(SettingsTest, canLoadLogLevel)
|
|||
auto constexpr ExpectedValue = TR_LOG_DEBUG;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue);
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ExpectedValue);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->log_level);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "debug");
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "debug"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->log_level);
|
||||
}
|
||||
|
||||
|
@ -161,9 +161,11 @@ TEST_F(SettingsTest, canSaveLogLevel)
|
|||
|
||||
settings.log_level = ExpectedValue;
|
||||
auto var = settings.save();
|
||||
auto val = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val));
|
||||
EXPECT_EQ(ExpectedValue, val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<int64_t>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(ExpectedValue, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadMode)
|
||||
|
@ -175,17 +177,15 @@ TEST_F(SettingsTest, canLoadMode)
|
|||
auto constexpr ExpectedValue = tr_mode_t{ 0777 };
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue);
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ExpectedValue);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->umask);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "0777");
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "0777"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->umask);
|
||||
}
|
||||
|
||||
|
@ -200,9 +200,11 @@ TEST_F(SettingsTest, canSaveMode)
|
|||
|
||||
settings.umask = ExpectedValue;
|
||||
auto var = settings.save();
|
||||
auto val = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, Key, &val));
|
||||
EXPECT_EQ("0777", val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<std::string_view>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ("0777"sv, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadPort)
|
||||
|
@ -214,10 +216,9 @@ TEST_F(SettingsTest, canLoadPort)
|
|||
auto constexpr ExpectedValue = tr_port::from_host(8080);
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue.host());
|
||||
settings.load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ExpectedValue.host());
|
||||
settings.load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings.peer_port);
|
||||
}
|
||||
|
||||
|
@ -232,9 +233,11 @@ TEST_F(SettingsTest, canSavePort)
|
|||
|
||||
settings.peer_port = ExpectedValue;
|
||||
auto var = settings.save();
|
||||
auto val = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val));
|
||||
EXPECT_EQ(ExpectedValue.host(), val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<int64_t>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(ExpectedValue.host(), *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadPreallocation)
|
||||
|
@ -246,17 +249,15 @@ TEST_F(SettingsTest, canLoadPreallocation)
|
|||
auto constexpr ExpectedValue = tr_open_files::Preallocation::Full;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, static_cast<int64_t>(ExpectedValue));
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, static_cast<int64_t>(ExpectedValue));
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->preallocation_mode);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "full");
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "full"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->preallocation_mode);
|
||||
}
|
||||
|
||||
|
@ -271,9 +272,11 @@ TEST_F(SettingsTest, canSavePreallocation)
|
|||
|
||||
settings.preallocation_mode = ExpectedValue;
|
||||
auto var = settings.save();
|
||||
auto val = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val));
|
||||
EXPECT_EQ(static_cast<int64_t>(ExpectedValue), val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<int64_t>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(static_cast<int64_t>(ExpectedValue), *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadSizeT)
|
||||
|
@ -283,10 +286,9 @@ TEST_F(SettingsTest, canLoadSizeT)
|
|||
auto settings = tr_session::Settings{};
|
||||
auto const expected_value = settings.queue_stalled_minutes + 5U;
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, expected_value);
|
||||
settings.load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, expected_value);
|
||||
settings.load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(expected_value, settings.queue_stalled_minutes);
|
||||
}
|
||||
|
||||
|
@ -299,9 +301,11 @@ TEST_F(SettingsTest, canSaveSizeT)
|
|||
|
||||
settings.queue_stalled_minutes = expected_value;
|
||||
auto var = settings.save();
|
||||
auto val = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val));
|
||||
EXPECT_EQ(expected_value, static_cast<size_t>(val));
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<int64_t>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(expected_value, static_cast<size_t>(*val));
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadString)
|
||||
|
@ -312,10 +316,9 @@ TEST_F(SettingsTest, canLoadString)
|
|||
auto settings = tr_session::Settings{};
|
||||
EXPECT_NE(ChangedValue, tr_session::Settings{}.bind_address_ipv4);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, ChangedValue);
|
||||
settings.load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ChangedValue);
|
||||
settings.load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ChangedValue, settings.bind_address_ipv4);
|
||||
}
|
||||
|
||||
|
@ -329,9 +332,11 @@ TEST_F(SettingsTest, canSaveString)
|
|||
|
||||
settings.bind_address_ipv4 = ChangedValue;
|
||||
auto var = settings.save();
|
||||
auto val = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, Key, &val));
|
||||
EXPECT_EQ(ChangedValue, val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<std::string_view>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(ChangedValue, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadTos)
|
||||
|
@ -343,17 +348,15 @@ TEST_F(SettingsTest, canLoadTos)
|
|||
auto const default_value = settings->peer_socket_tos;
|
||||
ASSERT_NE(ChangedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, 0x20);
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, 0x20);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ChangedValue, settings->peer_socket_tos);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "cs1");
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "cs1"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ChangedValue, settings->peer_socket_tos);
|
||||
}
|
||||
|
||||
|
@ -367,9 +370,11 @@ TEST_F(SettingsTest, canSaveTos)
|
|||
|
||||
settings.peer_socket_tos = tr_tos_t(0x20);
|
||||
auto var = settings.save();
|
||||
auto val = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, Key, &val));
|
||||
EXPECT_EQ(ChangedValue.toString(), val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<std::string_view>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ(ChangedValue.toString(), *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadVerify)
|
||||
|
@ -381,17 +386,15 @@ TEST_F(SettingsTest, canLoadVerify)
|
|||
auto const default_value = settings->torrent_added_verify_mode;
|
||||
ASSERT_NE(ChangedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "full");
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "full"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ChangedValue, settings->torrent_added_verify_mode);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ChangedValue);
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ChangedValue);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ChangedValue, settings->torrent_added_verify_mode);
|
||||
}
|
||||
|
||||
|
@ -405,9 +408,11 @@ TEST_F(SettingsTest, canSaveVerify)
|
|||
|
||||
settings.torrent_added_verify_mode = ChangedValue;
|
||||
auto var = settings.save();
|
||||
auto val = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, Key, &val));
|
||||
EXPECT_EQ("full", val);
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<std::string_view>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ("full"sv, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadPreferredTransport)
|
||||
|
@ -419,17 +424,15 @@ TEST_F(SettingsTest, canLoadPreferredTransport)
|
|||
auto const default_value = settings->preferred_transport;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue);
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ExpectedValue);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->preferred_transport);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddStrView(&var, Key, "tcp");
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, "tcp"sv);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->preferred_transport);
|
||||
}
|
||||
|
||||
|
@ -442,13 +445,13 @@ TEST_F(SettingsTest, canSavePreferredTransport)
|
|||
auto const default_value = settings.preferred_transport;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 100);
|
||||
settings.preferred_transport = ExpectedValue;
|
||||
var = settings.save();
|
||||
auto val = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&var, Key, &val));
|
||||
EXPECT_EQ("tcp", val);
|
||||
auto var = settings.save();
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val = map->value_if<std::string_view>(Key);
|
||||
ASSERT_TRUE(val);
|
||||
EXPECT_EQ("tcp"sv, *val);
|
||||
}
|
||||
|
||||
TEST_F(SettingsTest, canLoadSleepPerSecondsDuringVerify)
|
||||
|
@ -460,17 +463,15 @@ TEST_F(SettingsTest, canLoadSleepPerSecondsDuringVerify)
|
|||
auto const default_value = settings->sleep_per_seconds_during_verify;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, ExpectedValue.count());
|
||||
settings->load(var);
|
||||
auto map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, ExpectedValue.count());
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->sleep_per_seconds_during_verify);
|
||||
var.clear();
|
||||
|
||||
settings = std::make_unique<tr_session::Settings>();
|
||||
tr_variantInitDict(&var, 1);
|
||||
tr_variantDictAddInt(&var, Key, 90);
|
||||
settings->load(var);
|
||||
map = tr_variant::Map{ 1U };
|
||||
map.try_emplace(Key, 90);
|
||||
settings->load(tr_variant{ std::move(map) });
|
||||
EXPECT_EQ(ExpectedValue, settings->sleep_per_seconds_during_verify);
|
||||
}
|
||||
|
||||
|
@ -483,12 +484,11 @@ TEST_F(SettingsTest, canSaveSleepPerSecondsDuringVerify)
|
|||
auto const default_value = settings.sleep_per_seconds_during_verify;
|
||||
ASSERT_NE(ExpectedValue, default_value);
|
||||
|
||||
auto var = tr_variant{};
|
||||
tr_variantInitDict(&var, 100);
|
||||
settings.sleep_per_seconds_during_verify = ExpectedValue;
|
||||
var = settings.save();
|
||||
|
||||
auto val_raw = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&var, Key, &val_raw));
|
||||
EXPECT_EQ(ExpectedValue, std::chrono::milliseconds{ val_raw });
|
||||
auto var = settings.save();
|
||||
auto* const map = var.get_if<tr_variant::Map>();
|
||||
ASSERT_NE(map, nullptr);
|
||||
auto const val_raw = map->value_if<int64_t>(Key);
|
||||
ASSERT_TRUE(val_raw);
|
||||
EXPECT_EQ(ExpectedValue, std::chrono::milliseconds{ *val_raw });
|
||||
}
|
||||
|
|
|
@ -479,9 +479,7 @@ protected:
|
|||
{
|
||||
if (!settings_)
|
||||
{
|
||||
auto* settings = new tr_variant{};
|
||||
tr_variantInitDict(settings, 10);
|
||||
settings_.reset(settings);
|
||||
settings_ = std::make_shared<tr_variant>(tr_variant::make_map(10U));
|
||||
}
|
||||
|
||||
return settings_.get();
|
||||
|
|
|
@ -35,65 +35,69 @@ using VariantTest = ::testing::Test;
|
|||
|
||||
TEST_F(VariantTest, getType)
|
||||
{
|
||||
auto i = int64_t{};
|
||||
auto b = bool{};
|
||||
auto d = double{};
|
||||
auto sv = std::string_view{};
|
||||
auto v = tr_variant{};
|
||||
|
||||
v = 30;
|
||||
EXPECT_TRUE(tr_variantGetInt(&v, &i));
|
||||
EXPECT_EQ(30, i);
|
||||
EXPECT_TRUE(tr_variantGetReal(&v, &d));
|
||||
EXPECT_EQ(30, int(d));
|
||||
EXPECT_FALSE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_FALSE(tr_variantGetStrView(&v, &sv));
|
||||
auto i = v.value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(30, *i);
|
||||
auto d = v.value_if<double>();
|
||||
ASSERT_TRUE(d);
|
||||
EXPECT_EQ(30, static_cast<int>(*d));
|
||||
EXPECT_FALSE(v.holds_alternative<bool>());
|
||||
EXPECT_FALSE(v.holds_alternative<std::string_view>());
|
||||
|
||||
auto strkey = "foo"sv;
|
||||
v = tr_variant{ strkey };
|
||||
EXPECT_FALSE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
EXPECT_NE(std::data(strkey), std::data(sv));
|
||||
EXPECT_FALSE(v.holds_alternative<bool>());
|
||||
auto sv = v.value_if<std::string_view>();
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ(strkey, *sv);
|
||||
EXPECT_NE(std::data(strkey), std::data(*sv));
|
||||
EXPECT_EQ(std::size(strkey), std::size(*sv));
|
||||
|
||||
strkey = "anything"sv;
|
||||
v = tr_variant::unmanaged_string(strkey);
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
EXPECT_EQ(std::data(strkey), std::data(sv)); // literally the same memory
|
||||
EXPECT_EQ(std::size(strkey), std::size(sv));
|
||||
sv = v.value_if<std::string_view>();
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ(strkey, *sv);
|
||||
EXPECT_EQ(std::data(strkey), std::data(*sv)); // literally the same memory
|
||||
EXPECT_EQ(std::size(strkey), std::size(*sv));
|
||||
|
||||
strkey = "true"sv;
|
||||
v = tr_variant{ strkey };
|
||||
EXPECT_TRUE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_TRUE(b);
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
auto b = v.value_if<bool>();
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_TRUE(*b);
|
||||
sv = v.value_if<std::string_view>();
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ(strkey, *sv);
|
||||
|
||||
strkey = "false"sv;
|
||||
v = tr_variant{ strkey };
|
||||
EXPECT_TRUE(tr_variantGetBool(&v, &b));
|
||||
EXPECT_FALSE(b);
|
||||
EXPECT_TRUE(tr_variantGetStrView(&v, &sv));
|
||||
EXPECT_EQ(strkey, sv);
|
||||
b = v.value_if<bool>();
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_FALSE(*b);
|
||||
sv = v.value_if<std::string_view>();
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ(strkey, *sv);
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, parseInt)
|
||||
{
|
||||
auto constexpr Benc = "i64e"sv;
|
||||
auto constexpr ExpectVal = int64_t{ 64 };
|
||||
static auto constexpr Benc = "i64e"sv;
|
||||
static auto constexpr ExpectVal = int64_t{ 64 };
|
||||
|
||||
auto benc = Benc;
|
||||
auto const value = transmission::benc::impl::ParseInt(&benc);
|
||||
EXPECT_TRUE(value.has_value());
|
||||
assert(value.has_value());
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ(ExpectVal, *value);
|
||||
EXPECT_EQ(std::data(Benc) + std::size(Benc), std::data(benc));
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, parseIntWithMissingEnd)
|
||||
{
|
||||
auto constexpr Benc = "i64"sv;
|
||||
static auto constexpr Benc = "i64"sv;
|
||||
|
||||
auto benc = Benc;
|
||||
EXPECT_FALSE(transmission::benc::impl::ParseInt(&benc));
|
||||
|
@ -102,7 +106,7 @@ TEST_F(VariantTest, parseIntWithMissingEnd)
|
|||
|
||||
TEST_F(VariantTest, parseIntEmptyBuffer)
|
||||
{
|
||||
auto constexpr Benc = ""sv;
|
||||
static auto constexpr Benc = ""sv;
|
||||
|
||||
auto benc = Benc;
|
||||
EXPECT_FALSE(transmission::benc::impl::ParseInt(&benc));
|
||||
|
@ -111,7 +115,7 @@ TEST_F(VariantTest, parseIntEmptyBuffer)
|
|||
|
||||
TEST_F(VariantTest, parseIntWithBadDigits)
|
||||
{
|
||||
auto constexpr Benc = "i6z4e"sv;
|
||||
static auto constexpr Benc = "i6z4e"sv;
|
||||
|
||||
auto benc = Benc;
|
||||
EXPECT_FALSE(transmission::benc::impl::ParseInt(&benc));
|
||||
|
@ -120,20 +124,19 @@ TEST_F(VariantTest, parseIntWithBadDigits)
|
|||
|
||||
TEST_F(VariantTest, parseNegativeInt)
|
||||
{
|
||||
auto constexpr Benc = "i-3e"sv;
|
||||
auto constexpr Expected = int64_t{ -3 };
|
||||
static auto constexpr Benc = "i-3e"sv;
|
||||
static auto constexpr Expected = int64_t{ -3 };
|
||||
|
||||
auto benc = Benc;
|
||||
auto const value = transmission::benc::impl::ParseInt(&benc);
|
||||
EXPECT_TRUE(value.has_value());
|
||||
assert(value.has_value());
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ(Expected, *value);
|
||||
EXPECT_EQ(std::data(Benc) + std::size(Benc), std::data(benc));
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, parseNegativeWithLeadingZero)
|
||||
{
|
||||
auto constexpr Benc = "i-03e"sv;
|
||||
static auto constexpr Benc = "i-03e"sv;
|
||||
|
||||
auto benc = Benc;
|
||||
EXPECT_FALSE(transmission::benc::impl::ParseInt(&benc));
|
||||
|
@ -142,20 +145,19 @@ TEST_F(VariantTest, parseNegativeWithLeadingZero)
|
|||
|
||||
TEST_F(VariantTest, parseIntZero)
|
||||
{
|
||||
auto constexpr Benc = "i0e"sv;
|
||||
auto constexpr Expected = int64_t{ 0 };
|
||||
static auto constexpr Benc = "i0e"sv;
|
||||
static auto constexpr Expected = int64_t{ 0 };
|
||||
|
||||
auto benc = Benc;
|
||||
auto const value = transmission::benc::impl::ParseInt(&benc);
|
||||
EXPECT_TRUE(value.has_value());
|
||||
assert(value.has_value());
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ(Expected, *value);
|
||||
EXPECT_EQ(std::data(Benc) + std::size(Benc), std::data(benc));
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, parseIntWithLeadingZero)
|
||||
{
|
||||
auto constexpr Benc = "i04e"sv;
|
||||
static auto constexpr Benc = "i04e"sv;
|
||||
|
||||
auto benc = Benc;
|
||||
EXPECT_FALSE(transmission::benc::impl::ParseInt(&benc));
|
||||
|
@ -176,8 +178,7 @@ TEST_F(VariantTest, str)
|
|||
// good string
|
||||
inout = benc = "4:boat";
|
||||
value = ParseString(&inout);
|
||||
EXPECT_TRUE(value.has_value());
|
||||
assert(value.has_value());
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ("boat"sv, *value);
|
||||
EXPECT_EQ(std::data(benc) + std::size(benc), std::data(inout));
|
||||
|
||||
|
@ -190,16 +191,14 @@ TEST_F(VariantTest, str)
|
|||
// empty string
|
||||
inout = benc = "0:"sv;
|
||||
value = ParseString(&inout);
|
||||
EXPECT_TRUE(value.has_value());
|
||||
assert(value.has_value());
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ(""sv, *value);
|
||||
EXPECT_EQ(std::data(benc) + std::size(benc), std::data(inout));
|
||||
|
||||
// short string
|
||||
inout = benc = "3:boat";
|
||||
value = ParseString(&inout);
|
||||
EXPECT_TRUE(value.has_value());
|
||||
assert(value.has_value());
|
||||
ASSERT_TRUE(value);
|
||||
EXPECT_EQ("boa"sv, *value);
|
||||
EXPECT_EQ(std::data(benc) + benc.find('t'), std::data(inout));
|
||||
}
|
||||
|
@ -211,23 +210,27 @@ TEST_F(VariantTest, parse)
|
|||
|
||||
auto benc = "i64e"sv;
|
||||
auto var = serde.parse(benc).value_or(tr_variant{});
|
||||
auto i = int64_t{};
|
||||
EXPECT_TRUE(tr_variantGetInt(&var, &i));
|
||||
EXPECT_EQ(64, i);
|
||||
auto i = var.value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(64, *i);
|
||||
EXPECT_EQ(std::data(benc) + std::size(benc), serde.end());
|
||||
var.clear();
|
||||
|
||||
benc = "li64ei32ei16ee"sv;
|
||||
var = serde.parse(benc).value_or(tr_variant{});
|
||||
EXPECT_TRUE(var.holds_alternative<tr_variant::Vector>());
|
||||
auto* l = var.get_if<tr_variant::Vector>();
|
||||
ASSERT_NE(l, nullptr);
|
||||
EXPECT_EQ(std::data(benc) + std::size(benc), serde.end());
|
||||
EXPECT_EQ(3, tr_variantListSize(&var));
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&var, 0), &i));
|
||||
EXPECT_EQ(64, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&var, 1), &i));
|
||||
EXPECT_EQ(32, i);
|
||||
EXPECT_TRUE(tr_variantGetInt(tr_variantListChild(&var, 2), &i));
|
||||
EXPECT_EQ(16, i);
|
||||
ASSERT_EQ(3, std::size(*l));
|
||||
i = (*l)[0].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(64, *i);
|
||||
i = (*l)[1].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(32, *i);
|
||||
i = (*l)[2].value_if<int64_t>();
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(16, *i);
|
||||
EXPECT_EQ(benc, serde.to_string(var));
|
||||
var.clear();
|
||||
|
||||
|
@ -252,13 +255,7 @@ TEST_F(VariantTest, parse)
|
|||
|
||||
TEST_F(VariantTest, bencParseAndReencode)
|
||||
{
|
||||
struct LocalTest
|
||||
{
|
||||
std::string_view benc;
|
||||
bool is_good;
|
||||
};
|
||||
|
||||
auto constexpr Tests = std::array<LocalTest, 9>{ {
|
||||
static auto constexpr Tests = std::array<std::pair<std::string_view, bool>, 9>{ {
|
||||
{ "llleee"sv, true },
|
||||
{ "d3:cow3:moo4:spam4:eggse"sv, true },
|
||||
{ "d4:spaml1:a1:bee"sv, true },
|
||||
|
@ -273,14 +270,14 @@ TEST_F(VariantTest, bencParseAndReencode)
|
|||
auto serde = tr_variant_serde::benc();
|
||||
serde.inplace();
|
||||
|
||||
for (auto const& test : Tests)
|
||||
for (auto const& [benc, is_good] : Tests)
|
||||
{
|
||||
auto var = serde.parse(test.benc);
|
||||
EXPECT_EQ(test.is_good, var.has_value());
|
||||
auto var = serde.parse(benc);
|
||||
EXPECT_EQ(is_good, var.has_value());
|
||||
if (var)
|
||||
{
|
||||
EXPECT_EQ(test.benc.data() + test.benc.size(), serde.end());
|
||||
EXPECT_EQ(test.benc, serde.to_string(*var));
|
||||
EXPECT_EQ(benc.data() + benc.size(), serde.end());
|
||||
EXPECT_EQ(benc, serde.to_string(*var));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,13 +326,7 @@ TEST_F(VariantTest, bencMalformedIncompleteString)
|
|||
|
||||
TEST_F(VariantTest, bencToJson)
|
||||
{
|
||||
struct LocalTest
|
||||
{
|
||||
std::string_view benc;
|
||||
std::string_view expected;
|
||||
};
|
||||
|
||||
auto constexpr Tests = std::array<LocalTest, 5>{
|
||||
static auto constexpr Tests = std::array<std::pair<std::string_view, std::string_view>, 5>{
|
||||
{ { "i6e"sv, "6"sv },
|
||||
{ "d5:helloi1e5:worldi2ee"sv, R"({"hello":1,"world":2})"sv },
|
||||
{ "d5:helloi1e5:worldi2e3:fooli1ei2ei3eee"sv, R"({"foo":[1,2,3],"hello":1,"world":2})"sv },
|
||||
|
@ -349,10 +340,10 @@ TEST_F(VariantTest, bencToJson)
|
|||
benc_serde.inplace();
|
||||
json_serde.compact();
|
||||
|
||||
for (auto const& test : Tests)
|
||||
for (auto const& [benc, expected] : Tests)
|
||||
{
|
||||
auto top = benc_serde.parse(test.benc).value_or(tr_variant{});
|
||||
EXPECT_EQ(test.expected, json_serde.to_string(top));
|
||||
auto top = benc_serde.parse(benc).value_or(tr_variant{});
|
||||
EXPECT_EQ(expected, json_serde.to_string(top));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,51 +359,58 @@ TEST_F(VariantTest, merge)
|
|||
auto const s8 = tr_quark_new("s8"sv);
|
||||
|
||||
/* initial dictionary (default values) */
|
||||
tr_variant dest;
|
||||
tr_variantInitDict(&dest, 10);
|
||||
tr_variantDictAddInt(&dest, i1, 1);
|
||||
tr_variantDictAddInt(&dest, i2, 2);
|
||||
tr_variantDictAddInt(&dest, i4, -35); /* remains untouched */
|
||||
tr_variantDictAddStrView(&dest, s5, "abc");
|
||||
tr_variantDictAddStrView(&dest, s6, "def");
|
||||
tr_variantDictAddStrView(&dest, s7, "127.0.0.1"); /* remains untouched */
|
||||
auto dest = tr_variant::make_map(6U);
|
||||
auto* map = dest.get_if<tr_variant::Map>();
|
||||
map->try_emplace(i1, 1);
|
||||
map->try_emplace(i2, 2);
|
||||
map->try_emplace(i4, -35); /* remains untouched */
|
||||
map->try_emplace(s5, "abc");
|
||||
map->try_emplace(s6, "def");
|
||||
map->try_emplace(s7, "127.0.0.1"); /* remains untouched */
|
||||
|
||||
/* new dictionary, will overwrite items in dest */
|
||||
tr_variant src;
|
||||
tr_variantInitDict(&src, 10);
|
||||
tr_variantDictAddInt(&src, i1, 1); /* same value */
|
||||
tr_variantDictAddInt(&src, i2, 4); /* new value */
|
||||
tr_variantDictAddInt(&src, i3, 3); /* new key:value */
|
||||
tr_variantDictAddStrView(&src, s5, "abc"); /* same value */
|
||||
tr_variantDictAddStrView(&src, s6, "xyz"); /* new value */
|
||||
tr_variantDictAddStrView(&src, s8, "ghi"); /* new key:value */
|
||||
auto src = tr_variant::make_map(6U);
|
||||
map = src.get_if<tr_variant::Map>();
|
||||
map->try_emplace(i1, 1); /* same value */
|
||||
map->try_emplace(i2, 4); /* new value */
|
||||
map->try_emplace(i3, 3); /* new key:value */
|
||||
map->try_emplace(s5, "abc"); /* same value */
|
||||
map->try_emplace(s6, "xyz"); /* new value */
|
||||
map->try_emplace(s8, "ghi"); /* new key:value */
|
||||
|
||||
tr_variantMergeDicts(&dest, /*const*/ &src);
|
||||
dest.merge(src);
|
||||
|
||||
auto i = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&dest, i1, &i));
|
||||
EXPECT_EQ(1, i);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&dest, i2, &i));
|
||||
EXPECT_EQ(4, i);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&dest, i3, &i));
|
||||
EXPECT_EQ(3, i);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&dest, i4, &i));
|
||||
EXPECT_EQ(-35, i);
|
||||
auto sv = std::string_view{};
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&dest, s5, &sv));
|
||||
EXPECT_EQ("abc"sv, sv);
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&dest, s6, &sv));
|
||||
EXPECT_EQ("xyz"sv, sv);
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&dest, s7, &sv));
|
||||
EXPECT_EQ("127.0.0.1"sv, sv);
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&dest, s8, &sv));
|
||||
EXPECT_EQ("ghi"sv, sv);
|
||||
map = dest.get_if<tr_variant::Map>();
|
||||
auto i = map->value_if<int64_t>(i1);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(1, *i);
|
||||
i = map->value_if<int64_t>(i2);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(4, *i);
|
||||
i = map->value_if<int64_t>(i3);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(3, *i);
|
||||
i = map->value_if<int64_t>(i4);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(-35, *i);
|
||||
auto sv = map->value_if<std::string_view>(s5);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("abc"sv, *sv);
|
||||
sv = map->value_if<std::string_view>(s6);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("xyz"sv, *sv);
|
||||
sv = map->value_if<std::string_view>(s7);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("127.0.0.1"sv, *sv);
|
||||
sv = map->value_if<std::string_view>(s8);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ("ghi"sv, *sv);
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, stackSmash)
|
||||
{
|
||||
// make a nested list of list of lists.
|
||||
int constexpr Depth = STACK_SMASH_DEPTH;
|
||||
static int constexpr Depth = STACK_SMASH_DEPTH;
|
||||
std::string const in = std::string(Depth, 'l') + std::string(Depth, 'e');
|
||||
|
||||
// confirm that it fails instead of crashing
|
||||
|
@ -430,42 +428,48 @@ TEST_F(VariantTest, boolAndIntRecast)
|
|||
auto const key3 = tr_quark_new("key3"sv);
|
||||
auto const key4 = tr_quark_new("key4"sv);
|
||||
|
||||
auto top = tr_variant{};
|
||||
tr_variantInitDict(&top, 10);
|
||||
tr_variantDictAddBool(&top, key1, false);
|
||||
tr_variantDictAddBool(&top, key2, 0); // NOLINT modernize-use-bool-literals
|
||||
tr_variantDictAddInt(&top, key3, true); // NOLINT readability-implicit-bool-conversion
|
||||
tr_variantDictAddInt(&top, key4, 1);
|
||||
auto top = tr_variant::make_map(4U);
|
||||
auto* map = top.get_if<tr_variant::Map>();
|
||||
map->try_emplace(key1, false);
|
||||
map->try_emplace(key2, 0);
|
||||
map->try_emplace(key3, true);
|
||||
map->try_emplace(key4, 1);
|
||||
|
||||
// confirm we can read both bools and ints as bools
|
||||
auto b = bool{};
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&top, key1, &b));
|
||||
EXPECT_FALSE(b);
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&top, key2, &b));
|
||||
EXPECT_FALSE(b);
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&top, key3, &b));
|
||||
EXPECT_TRUE(b);
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&top, key4, &b));
|
||||
EXPECT_TRUE(b);
|
||||
auto b = map->value_if<bool>(key1);
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_FALSE(*b);
|
||||
b = map->value_if<bool>(key2);
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_FALSE(*b);
|
||||
b = map->value_if<bool>(key3);
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_TRUE(*b);
|
||||
b = map->value_if<bool>(key4);
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_TRUE(*b);
|
||||
|
||||
// confirm we can read both bools and ints as ints
|
||||
auto i = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key1, &i));
|
||||
EXPECT_EQ(0, i);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key2, &i));
|
||||
EXPECT_EQ(0, i);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key3, &i));
|
||||
EXPECT_NE(0, i);
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key4, &i));
|
||||
EXPECT_NE(0, i);
|
||||
auto i = map->value_if<int64_t>(key1);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(0, *i);
|
||||
i = map->value_if<int64_t>(key2);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(0, *i);
|
||||
i = map->value_if<int64_t>(key3);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_NE(0, *i);
|
||||
i = map->value_if<int64_t>(key4);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_NE(0, *i);
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, dictFindType)
|
||||
{
|
||||
auto constexpr ExpectedStr = "this-is-a-string"sv;
|
||||
auto constexpr ExpectedBool = true;
|
||||
auto constexpr ExpectedInt = 1234;
|
||||
auto constexpr ExpectedReal = 0.3;
|
||||
static auto constexpr ExpectedStr = "this-is-a-string"sv;
|
||||
static auto constexpr ExpectedBool = true;
|
||||
static auto constexpr ExpectedInt = 1234;
|
||||
static auto constexpr ExpectedReal = 0.3;
|
||||
|
||||
auto const key_bool = tr_quark_new("this-is-a-bool"sv);
|
||||
auto const key_real = tr_quark_new("this-is-a-real"sv);
|
||||
|
@ -474,50 +478,50 @@ TEST_F(VariantTest, dictFindType)
|
|||
auto const key_unknown = tr_quark_new("this-is-a-missing-entry"sv);
|
||||
|
||||
// populate a dict
|
||||
tr_variant top;
|
||||
tr_variantInitDict(&top, 0);
|
||||
tr_variantDictAddBool(&top, key_bool, ExpectedBool);
|
||||
tr_variantDictAddInt(&top, key_int, ExpectedInt);
|
||||
tr_variantDictAddReal(&top, key_real, ExpectedReal);
|
||||
tr_variantDictAddStr(&top, key_str, ExpectedStr.data());
|
||||
auto top = tr_variant::make_map(4U);
|
||||
auto* map = top.get_if<tr_variant::Map>();
|
||||
map->try_emplace(key_bool, ExpectedBool);
|
||||
map->try_emplace(key_int, ExpectedInt);
|
||||
map->try_emplace(key_real, ExpectedReal);
|
||||
map->try_emplace(key_str, ExpectedStr);
|
||||
|
||||
// look up the keys as strings
|
||||
auto sv = std::string_view{};
|
||||
EXPECT_FALSE(tr_variantDictFindStrView(&top, key_bool, &sv));
|
||||
EXPECT_FALSE(tr_variantDictFindStrView(&top, key_real, &sv));
|
||||
EXPECT_FALSE(tr_variantDictFindStrView(&top, key_int, &sv));
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&top, key_str, &sv));
|
||||
EXPECT_EQ(ExpectedStr, sv);
|
||||
EXPECT_TRUE(tr_variantDictFindStrView(&top, key_str, &sv));
|
||||
EXPECT_EQ(ExpectedStr, sv);
|
||||
EXPECT_FALSE(tr_variantDictFindStrView(&top, key_unknown, &sv));
|
||||
EXPECT_FALSE(tr_variantDictFindStrView(&top, key_unknown, &sv));
|
||||
EXPECT_FALSE(map->value_if<std::string_view>(key_bool));
|
||||
EXPECT_FALSE(map->value_if<std::string_view>(key_real));
|
||||
EXPECT_FALSE(map->value_if<std::string_view>(key_int));
|
||||
auto sv = map->value_if<std::string_view>(key_str);
|
||||
ASSERT_TRUE(sv);
|
||||
EXPECT_EQ(ExpectedStr, *sv);
|
||||
EXPECT_FALSE(map->value_if<std::string_view>(key_unknown));
|
||||
|
||||
// look up the keys as bools
|
||||
auto b = bool{};
|
||||
EXPECT_FALSE(tr_variantDictFindBool(&top, key_int, &b));
|
||||
EXPECT_FALSE(tr_variantDictFindBool(&top, key_real, &b));
|
||||
EXPECT_FALSE(tr_variantDictFindBool(&top, key_str, &b));
|
||||
EXPECT_TRUE(tr_variantDictFindBool(&top, key_bool, &b));
|
||||
EXPECT_FALSE(map->value_if<bool>(key_int));
|
||||
EXPECT_FALSE(map->value_if<bool>(key_real));
|
||||
EXPECT_FALSE(map->value_if<bool>(key_str));
|
||||
auto b = map->value_if<bool>(key_bool);
|
||||
ASSERT_TRUE(b);
|
||||
EXPECT_EQ(ExpectedBool, b);
|
||||
EXPECT_FALSE(map->value_if<bool>(key_unknown));
|
||||
|
||||
// look up the keys as doubles
|
||||
auto d = double{};
|
||||
EXPECT_FALSE(tr_variantDictFindReal(&top, key_bool, &d));
|
||||
EXPECT_TRUE(tr_variantDictFindReal(&top, key_int, &d));
|
||||
EXPECT_EQ(ExpectedInt, std::lrint(d));
|
||||
EXPECT_FALSE(tr_variantDictFindReal(&top, key_str, &d));
|
||||
EXPECT_TRUE(tr_variantDictFindReal(&top, key_real, &d));
|
||||
EXPECT_EQ(std::lrint(ExpectedReal * 100), std::lrint(d * 100));
|
||||
EXPECT_FALSE(map->value_if<double>(key_bool));
|
||||
auto d = map->value_if<double>(key_int);
|
||||
ASSERT_TRUE(d);
|
||||
EXPECT_EQ(static_cast<double>(ExpectedInt), *d);
|
||||
EXPECT_FALSE(map->value_if<double>(key_str));
|
||||
d = map->value_if<double>(key_real);
|
||||
ASSERT_TRUE(d);
|
||||
EXPECT_EQ(ExpectedReal, *d);
|
||||
|
||||
// look up the keys as ints
|
||||
auto i = int64_t{};
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key_bool, &i));
|
||||
EXPECT_EQ(ExpectedBool ? 1 : 0, i);
|
||||
EXPECT_FALSE(tr_variantDictFindInt(&top, key_real, &i));
|
||||
EXPECT_FALSE(tr_variantDictFindInt(&top, key_str, &i));
|
||||
EXPECT_TRUE(tr_variantDictFindInt(&top, key_int, &i));
|
||||
EXPECT_EQ(ExpectedInt, i);
|
||||
auto i = map->value_if<int64_t>(key_bool);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(ExpectedBool ? 1 : 0, *i);
|
||||
EXPECT_FALSE(map->value_if<int64_t>(key_real));
|
||||
EXPECT_FALSE(map->value_if<int64_t>(key_str));
|
||||
i = map->value_if<int64_t>(key_int);
|
||||
ASSERT_TRUE(i);
|
||||
EXPECT_EQ(ExpectedInt, *i);
|
||||
}
|
||||
|
||||
TEST_F(VariantTest, variantFromBufFuzz)
|
||||
|
|
Loading…
Reference in a new issue