blob: e23aff234115cd79611e8bea0e5bec67c6f44747 [file]
// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "cbor/cbor.h"
#include <memory>
#include "absl/status/status.h"
#include "absl/status/status_macros.h" // IWYU pragma: keep
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "cppbor/cppbor.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace cbor {
namespace {
using ::testing::Eq;
TEST(ItemViewTest, BoolType) {
auto item = std::make_unique<cppbor::Bool>(true);
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kBool);
auto val = view.GetBool();
ABSL_ASSERT_OK(val);
EXPECT_TRUE(*val);
}
TEST(ItemViewTest, FloatType) {
auto item = std::make_unique<cppbor::Float>(1.5f);
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kFloat);
auto val = view.GetFloat();
ABSL_ASSERT_OK(val);
EXPECT_FLOAT_EQ(*val, 1.5f);
}
TEST(ItemViewTest, DoubleType) {
auto item = std::make_unique<cppbor::Double>(2.5);
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kDouble);
auto val = view.GetDouble();
ABSL_ASSERT_OK(val);
EXPECT_DOUBLE_EQ(*val, 2.5);
}
TEST(ItemViewTest, Int64Type) {
auto item = std::make_unique<cppbor::Nint>(-42);
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kInt64);
auto val = view.GetInt64();
ABSL_ASSERT_OK(val);
EXPECT_EQ(*val, -42);
}
TEST(ItemViewTest, Uint64Type) {
auto item = std::make_unique<cppbor::Uint>(42);
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kUint64);
auto val = view.GetUint64();
ABSL_ASSERT_OK(val);
EXPECT_EQ(*val, 42);
}
TEST(ItemViewTest, StringType) {
auto item = std::make_unique<cppbor::Tstr>("hello");
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kString);
auto val = view.GetString();
ABSL_ASSERT_OK(val);
EXPECT_EQ(*val, "hello");
}
TEST(ItemViewTest, ByteStringType) {
auto item = std::make_unique<cppbor::Bstr>("world");
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kByteString);
auto val = view.GetByteString();
ABSL_ASSERT_OK(val);
EXPECT_EQ(*val, "world");
}
TEST(ItemViewTest, MapType) {
auto item = std::make_unique<cppbor::Map>();
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kMap);
auto val = view.GetMap();
ABSL_ASSERT_OK(val);
}
TEST(ItemViewTest, ArrayType) {
auto item = std::make_unique<cppbor::Array>();
ItemView view(item.get());
EXPECT_EQ(view.type(), ItemView::Type::kArray);
auto val = view.GetArray();
ABSL_ASSERT_OK(val);
}
TEST(ItemViewTest, IsNull) {
auto item = std::make_unique<cppbor::Null>();
ItemView view(item.get());
EXPECT_TRUE(view.IsNull());
}
TEST(ItemViewTest, Failures) {
auto item = std::make_unique<cppbor::Uint>(42);
ItemView view(item.get());
EXPECT_THAT(view.GetBool().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_THAT(view.GetFloat().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_THAT(view.GetDouble().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_THAT(view.GetString().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_THAT(view.GetByteString().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_THAT(view.GetMap().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_THAT(view.GetArray().status().code(),
Eq(absl::StatusCode::kInvalidArgument));
}
TEST(MapViewTest, GetMethods) {
auto map = std::make_unique<cppbor::Map>();
map->add("bool", cppbor::Bool(true));
map->add("int", cppbor::Uint(42));
map->add("string", cppbor::Tstr("value"));
map->add(42, cppbor::Uint(24));
MapView view(map.get());
auto bool_val = view.GetBool("bool");
ABSL_ASSERT_OK(bool_val);
EXPECT_TRUE(*bool_val);
auto int_val = view.GetUint64("int");
ABSL_ASSERT_OK(int_val);
EXPECT_EQ(*int_val, 42);
auto str_val = view.GetString("string");
ABSL_ASSERT_OK(str_val);
EXPECT_EQ(*str_val, "value");
auto int_key_val = view.GetInt64(42);
ABSL_ASSERT_OK(int_key_val);
EXPECT_EQ(*int_key_val, 24);
}
TEST(MapViewTest, GetOptional) {
auto map = std::make_unique<cppbor::Map>();
map->add("bool", cppbor::Bool(true));
MapView view(map.get());
EXPECT_TRUE(view.GetOptionalBool("bool").has_value());
EXPECT_TRUE(view.GetOptionalBool("bool").value());
EXPECT_FALSE(view.GetOptionalBool("nonexistent").has_value());
}
TEST(MapViewTest, Failures) {
auto map = std::make_unique<cppbor::Map>();
MapView view(map.get());
EXPECT_THAT(view.GetBool("nonexistent").status().code(),
Eq(absl::StatusCode::kInvalidArgument));
}
TEST(ArrayViewTest, GetMethods) {
auto array = std::make_unique<cppbor::Array>();
array->add(cppbor::Bool(true));
array->add(cppbor::Uint(42));
ArrayView view(array.get());
EXPECT_EQ(view.size(), 2);
EXPECT_FALSE(view.empty());
auto bool_val = view.GetBool(0);
ABSL_ASSERT_OK(bool_val);
EXPECT_TRUE(*bool_val);
auto int_val = view.GetUint64(1);
ABSL_ASSERT_OK(int_val);
EXPECT_EQ(*int_val, 42);
}
TEST(ArrayViewTest, Failures) {
auto array = std::make_unique<cppbor::Array>();
ArrayView view(array.get());
EXPECT_THAT(view.GetBool(0).status().code(),
Eq(absl::StatusCode::kInvalidArgument));
EXPECT_EQ(view.value_type(0), ItemView::Type::kUnknown);
EXPECT_EQ(view.value_type(1), ItemView::Type::kUnknown);
array->add(cppbor::Uint(42));
EXPECT_EQ(view.value_type(0), ItemView::Type::kUint64);
EXPECT_EQ(view.value_type(1), ItemView::Type::kUnknown);
}
} // namespace
} // namespace cbor