blob: 4a0ce6a54a1726045493c7afef39290e66cee8e4 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/values.h"
#include "components/cbor/reader.h"
#include "components/cbor/values.h"
#include "components/cbor/writer.h"
#include "services/data_decoder/cbor_parser_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace data_decoder {
namespace {
void CopyResultCallback(absl::optional<::base::Value>& output_result,
absl::optional<std::string>& output_error,
absl::optional<::base::Value> result,
const absl::optional<std::string>& error) {
output_result = std::move(result);
output_error = error;
}
} // namespace
using CborToValueTest = testing::Test;
TEST_F(CborToValueTest, SuccesfulParseValues) {
struct {
std::string name;
std::vector<uint8_t> input;
base::Value expected_result;
} test_cases[] = {
{
"Unsigned",
{0x18, 0x64}, // 100
base::Value(100),
},
{
"Negative",
{0x38, 0x63}, //-100
base::Value(-100),
},
{
"Array", // [100, false, "string", {"k": "v"}]
{0x84, 0x18, 0x64, 0xF4, 0x66, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
0xA1, 0x61, 0x6B, 0x61, 0x76},
base::Value(base::Value::List()
.Append(100)
.Append(false)
.Append("string")
.Append(base::Value::Dict().Set("k", "v"))),
},
{"Map", // {"bool": true, "array": [100], "number": 100}
{0xA3, 0x64, 0x62, 0x6F, 0x6F, 0x6C, 0xF5, 0x65, 0x61,
0x72, 0x72, 0x61, 0x79, 0x81, 0x18, 0x64, 0x66, 0x6E,
0x75, 0x6D, 0x62, 0x65, 0x72, 0x18, 0x64},
base::Value(base::Value::Dict()
.Set("bool", true)
.Set("array", base::Value::List().Append(100))
.Set("number", 100))},
{"SimpleBooleanTrue", {0xF5}, base::Value(true)},
{"SimpleBooleanFalse", {0xF4}, base::Value(false)},
{"String", {0x64, 0x63, 0x62, 0x6F, 0x72}, base::Value("cbor")},
{"ByteString",
{0x44, 0x63, 0x62, 0x6f, 0x72},
base::Value(cbor::Value::BinaryValue({0x63, 0x62, 0x6f, 0x72}))}};
for (const auto& test_case : test_cases) {
SCOPED_TRACE(test_case.name);
CborParserImpl parser;
absl::optional<base::Value> result;
absl::optional<std::string> error;
parser.Parse(
test_case.input,
base::BindOnce(&CopyResultCallback, std::ref(result), std::ref(error)));
ASSERT_TRUE(result.has_value());
EXPECT_EQ(result.value(), test_case.expected_result);
EXPECT_FALSE(error.has_value());
}
}
TEST_F(CborToValueTest, FailingParseValues) {
const std::string invalid_error = "Error unexpected CBOR value.";
struct {
std::string name;
std::vector<uint8_t> input;
std::string expected_error;
} test_cases[] = {
{"Null", {0xF6}, invalid_error},
{"InvalidMapKeyType", // {100: "100", "k": "v"} - 100 is an invalid key
{0xA2, 0x18, 0x64, 0x63, 0x31, 0x30, 0x30, 0x61, 0x6B, 0x61, 0x76},
invalid_error},
{"NestedInvalidKey", // [{100: "100", "k": "v"}] - 100 is an invalid key
{0x81, 0xA2, 0x18, 0x64, 0x63, 0x31, 0x30, 0x30, 0x61, 0x6B, 0x61, 0x76},
invalid_error},
{"DuplicateMapKeys", // {"k": "v1", "k": "v2"}
{0xA2, 0x61, 0x6B, 0x62, 0x76, 0x31, 0x61, 0x6B, 0x62, 0x76, 0x32},
cbor::Reader::ErrorCodeToString(
cbor::Reader::DecoderError::DUPLICATE_KEY)}};
for (const auto& test_case : test_cases) {
SCOPED_TRACE(test_case.name);
CborParserImpl parser;
absl::optional<base::Value> result;
absl::optional<std::string> error;
parser.Parse(
test_case.input,
base::BindOnce(&CopyResultCallback, std::ref(result), std::ref(error)));
ASSERT_TRUE(error.has_value());
EXPECT_EQ(error.value(), test_case.expected_error);
EXPECT_FALSE(result.has_value());
}
}
} // namespace data_decoder