Context improvements (#457)
* Expose the ContextValueType so callers can use it to get at key values. * Add a const char * overload for construction * Remove explicit conversion which adds an extra move construction. const char* implicitly converts to std::string
This commit is contained in:
parent
e031696bce
commit
0b2b688e72
@ -1,7 +1,7 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-Debug",
|
||||
"name": "x64-DebugWithTests",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
|
||||
@ -21,6 +21,7 @@ namespace Azure { namespace Core {
|
||||
* @brief ContextValue exists as a substitute for variant which isn't available until C++17
|
||||
*/
|
||||
class ContextValue {
|
||||
public:
|
||||
enum class ContextValueType
|
||||
{
|
||||
Undefined,
|
||||
@ -30,6 +31,7 @@ namespace Azure { namespace Core {
|
||||
UniquePtr
|
||||
};
|
||||
|
||||
private:
|
||||
ContextValueType m_contextValueType;
|
||||
union
|
||||
{
|
||||
@ -40,12 +42,23 @@ namespace Azure { namespace Core {
|
||||
};
|
||||
|
||||
public:
|
||||
ContextValue() noexcept : m_contextValueType(ContextValueType::Undefined), m_b(false) {}
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 26495)
|
||||
#endif
|
||||
|
||||
ContextValue() noexcept : m_contextValueType(ContextValueType::Undefined) {}
|
||||
ContextValue(bool b) noexcept : m_contextValueType(ContextValueType::Bool), m_b(b) {}
|
||||
ContextValue(int i) noexcept : m_contextValueType(ContextValueType::Int), m_i(i) {}
|
||||
ContextValue(const std::string& s) : m_contextValueType(ContextValueType::StdString), m_s(s) {}
|
||||
ContextValue(std::string&& s) noexcept
|
||||
: m_contextValueType(ContextValueType::UniquePtr), m_s(std::move(s))
|
||||
|
||||
ContextValue(const char* s)
|
||||
: m_contextValueType(ContextValueType::StdString), m_s(s)
|
||||
{
|
||||
}
|
||||
|
||||
ContextValue(std::string&& s)
|
||||
: m_contextValueType(ContextValueType::StdString), m_s(std::move(s))
|
||||
{
|
||||
}
|
||||
|
||||
@ -74,6 +87,9 @@ namespace Azure { namespace Core {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
~ContextValue()
|
||||
{
|
||||
|
||||
@ -31,7 +31,7 @@ add_executable (
|
||||
transport_adapter.cpp
|
||||
transport_adapter.hpp
|
||||
uuid.cpp
|
||||
)
|
||||
context.cpp)
|
||||
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE azure-core)
|
||||
add_gtest(${TARGET_NAME})
|
||||
|
||||
162
sdk/core/azure-core/test/ut/context.cpp
Normal file
162
sdk/core/azure-core/test/ut/context.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "context.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace Azure::Core;
|
||||
|
||||
TEST(Context, Basic)
|
||||
{
|
||||
Context context;
|
||||
auto& valueT = context["key"];
|
||||
EXPECT_FALSE(context.HasKey(""));
|
||||
EXPECT_FALSE(context.HasKey("key"));
|
||||
|
||||
auto kind = valueT.Alternative();
|
||||
EXPECT_TRUE(kind == ContextValue::ContextValueType::Undefined);
|
||||
}
|
||||
|
||||
TEST(Context, BasicBool)
|
||||
{
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("key", true);
|
||||
auto& valueT = c2["key"];
|
||||
auto value = valueT.Get<bool>();
|
||||
EXPECT_TRUE(value == true);
|
||||
|
||||
auto kind = valueT.Alternative();
|
||||
EXPECT_TRUE(kind == ContextValue::ContextValueType::Bool);
|
||||
}
|
||||
|
||||
TEST(Context, BasicInt)
|
||||
{
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("key", 123);
|
||||
auto& valueT = c2["key"];
|
||||
auto value = valueT.Get<int>();
|
||||
EXPECT_TRUE(value == 123);
|
||||
|
||||
auto kind = valueT.Alternative();
|
||||
EXPECT_TRUE(kind == ContextValue::ContextValueType::Int);
|
||||
}
|
||||
|
||||
TEST(Context, BasicStdString)
|
||||
{
|
||||
std::string s("Test String");
|
||||
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("key", s);
|
||||
auto& valueT = c2["key"];
|
||||
auto value = valueT.Get<std::string>();
|
||||
EXPECT_TRUE(value == s);
|
||||
|
||||
auto kind = valueT.Alternative();
|
||||
EXPECT_TRUE(kind == ContextValue::ContextValueType::StdString);
|
||||
}
|
||||
|
||||
TEST(Context, BasicChar)
|
||||
{
|
||||
const char* str = "Test String";
|
||||
std::string s(str);
|
||||
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("key", str);
|
||||
auto& valueT = c2["key"];
|
||||
auto value = valueT.Get<std::string>();
|
||||
EXPECT_TRUE(value == s);
|
||||
|
||||
auto kind = valueT.Alternative();
|
||||
EXPECT_TRUE(kind == ContextValue::ContextValueType::StdString);
|
||||
}
|
||||
|
||||
TEST(Context, Alternative)
|
||||
{
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("key", 123);
|
||||
auto& valueT1 = c2["key"];
|
||||
auto& valueT2 = c2["otherKey"];
|
||||
|
||||
EXPECT_TRUE(valueT1.Alternative() == ContextValue::ContextValueType::Int);
|
||||
EXPECT_TRUE(valueT2.Alternative() == ContextValue::ContextValueType::Undefined);
|
||||
}
|
||||
|
||||
TEST(Context, Chain)
|
||||
{
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("c2", 123);
|
||||
auto c3 = c2.WithValue("c3", 456);
|
||||
auto c4 = c3.WithValue("c4", 789);
|
||||
auto c5 = c4.WithValue("c5", "5");
|
||||
auto c6 = c5.WithValue("c6", "6");
|
||||
auto c7 = c6.WithValue("c7", "7");
|
||||
auto finalContext = c7.WithValue("finalContext", "Final");
|
||||
|
||||
auto& valueT2 = finalContext["c2"];
|
||||
auto& valueT3 = finalContext["c3"];
|
||||
auto& valueT4 = finalContext["c4"];
|
||||
auto& valueT5 = finalContext["c5"];
|
||||
auto& valueT6 = finalContext["c6"];
|
||||
auto& valueT7 = finalContext["c7"];
|
||||
auto& valueT8 = finalContext["finalContext"];
|
||||
auto& valueT9 = finalContext["otherKey"];
|
||||
|
||||
EXPECT_TRUE(valueT2.Alternative() == ContextValue::ContextValueType::Int);
|
||||
EXPECT_TRUE(valueT3.Alternative() == ContextValue::ContextValueType::Int);
|
||||
EXPECT_TRUE(valueT4.Alternative() == ContextValue::ContextValueType::Int);
|
||||
EXPECT_TRUE(valueT5.Alternative() == ContextValue::ContextValueType::StdString);
|
||||
EXPECT_TRUE(valueT6.Alternative() == ContextValue::ContextValueType::StdString);
|
||||
EXPECT_TRUE(valueT7.Alternative() == ContextValue::ContextValueType::StdString);
|
||||
EXPECT_TRUE(valueT8.Alternative() == ContextValue::ContextValueType::StdString);
|
||||
EXPECT_TRUE(valueT9.Alternative() == ContextValue::ContextValueType::Undefined);
|
||||
|
||||
auto value = valueT2.Get<int>();
|
||||
EXPECT_TRUE(value == 123);
|
||||
value = valueT3.Get<int>();
|
||||
EXPECT_TRUE(value == 456);
|
||||
value = valueT4.Get<int>();
|
||||
EXPECT_TRUE(value == 789);
|
||||
|
||||
auto str = valueT5.Get<std::string>();
|
||||
EXPECT_TRUE(str == "5");
|
||||
str = valueT6.Get<std::string>();
|
||||
EXPECT_TRUE(str == "6");
|
||||
str = valueT7.Get<std::string>();
|
||||
EXPECT_TRUE(str == "7");
|
||||
|
||||
str = valueT8.Get<std::string>();
|
||||
EXPECT_TRUE(str == "Final");
|
||||
}
|
||||
|
||||
TEST(Context, MatchingKeys)
|
||||
{
|
||||
Context context;
|
||||
// New context from previous
|
||||
auto c2 = context.WithValue("key", 123);
|
||||
auto c3 = c2.WithValue("key", 456);
|
||||
|
||||
auto& valueT2 = c2["key"];
|
||||
auto& valueT3 = c3["key"];
|
||||
auto& missing = c3["otherKey"];
|
||||
|
||||
EXPECT_TRUE(valueT2.Alternative() == ContextValue::ContextValueType::Int);
|
||||
EXPECT_TRUE(valueT3.Alternative() == ContextValue::ContextValueType::Int);
|
||||
EXPECT_TRUE(missing.Alternative() == ContextValue::ContextValueType::Undefined);
|
||||
|
||||
auto value = valueT2.Get<int>();
|
||||
EXPECT_TRUE(value == 123);
|
||||
value = valueT3.Get<int>();
|
||||
EXPECT_TRUE(value == 456);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user