blob: ade8c1a6788a4d0a4063fd276bbea6cc511abb4f [file]
// Copyright 2025 The Pigweed Authors
//
// 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 "pw_log_tokenized/fields.h"
#include <array>
#include <string_view>
#include <utility>
#include "pw_status/status_with_size.h"
#include "pw_unit_test/constexpr.h"
#include "pw_unit_test/framework.h"
namespace {
using pw::Status;
using pw::StatusWithSize;
using pw::log_tokenized::ParseFields;
struct Field {
std::string_view key;
std::string_view value;
};
PW_CONSTEXPR_TEST(ParseFields, EmptyString, {
size_t fields_parsed = 0;
StatusWithSize result =
ParseFields("", [&fields_parsed](std::string_view, std::string_view) {
fields_parsed += 1;
});
PW_TEST_EXPECT_OK(result.status());
PW_TEST_EXPECT_EQ(0u, result.size());
PW_TEST_EXPECT_EQ(0u, fields_parsed);
});
PW_CONSTEXPR_TEST(ParseFields, NoFields, {
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"Hello world", [&fields_parsed](std::string_view, std::string_view) {
fields_parsed += 1;
});
PW_TEST_EXPECT_OK(result.status());
PW_TEST_EXPECT_EQ(0u, result.size());
PW_TEST_EXPECT_EQ(0u, fields_parsed);
});
PW_CONSTEXPR_TEST(ParseFields, OneField, {
std::array<Field, 1> fields;
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"■msg♦Hello world",
[&fields, &fields_parsed](std::string_view key, std::string_view val) {
fields[fields_parsed++] = {key, val};
});
PW_TEST_EXPECT_OK(result.status());
PW_TEST_ASSERT_EQ(1u, result.size());
PW_TEST_ASSERT_EQ(1u, fields_parsed);
PW_TEST_EXPECT_EQ("msg", fields[0].key);
PW_TEST_EXPECT_EQ("Hello world", fields[0].value);
});
PW_CONSTEXPR_TEST(ParseFields, MultipleFields, {
std::array<Field, 3> fields;
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"■msg♦Hello■module♦test■file♦test.cc",
[&fields, &fields_parsed](std::string_view key, std::string_view val) {
fields[fields_parsed++] = {key, val};
});
PW_TEST_EXPECT_OK(result.status());
PW_TEST_ASSERT_EQ(3u, result.size());
PW_TEST_ASSERT_EQ(3u, fields_parsed);
PW_TEST_EXPECT_EQ("msg", fields[0].key);
PW_TEST_EXPECT_EQ("Hello", fields[0].value);
PW_TEST_EXPECT_EQ("module", fields[1].key);
PW_TEST_EXPECT_EQ("test", fields[1].value);
PW_TEST_EXPECT_EQ("file", fields[2].key);
PW_TEST_EXPECT_EQ("test.cc", fields[2].value);
});
PW_CONSTEXPR_TEST(ParseFields, IncompleteField, {
size_t fields_parsed = 0;
StatusWithSize result =
ParseFields("■msg", [&fields_parsed](std::string_view, std::string_view) {
fields_parsed += 1;
});
PW_TEST_EXPECT_EQ(Status::DataLoss(), result.status());
PW_TEST_EXPECT_EQ(0u, result.size());
PW_TEST_EXPECT_EQ(0u, fields_parsed);
});
PW_CONSTEXPR_TEST(ParseFields, IncompleteFieldAfterOne, {
std::array<Field, 2> fields;
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"■msg♦Hello■key2",
[&fields, &fields_parsed](std::string_view key, std::string_view val) {
fields[fields_parsed++] = {key, val};
});
PW_TEST_EXPECT_EQ(Status::DataLoss(), result.status());
PW_TEST_EXPECT_EQ(1u, result.size());
PW_TEST_ASSERT_EQ(1u, fields_parsed);
PW_TEST_EXPECT_EQ("msg", fields[0].key);
PW_TEST_EXPECT_EQ("Hello", fields[0].value);
});
PW_CONSTEXPR_TEST(ParseFields, EmptyValue, {
std::array<Field, 1> fields;
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"■msg♦",
[&fields, &fields_parsed](std::string_view key, std::string_view val) {
fields[fields_parsed++] = {key, val};
});
PW_TEST_EXPECT_OK(result.status());
PW_TEST_ASSERT_EQ(1u, result.size());
PW_TEST_ASSERT_EQ(1u, fields_parsed);
PW_TEST_EXPECT_EQ("msg", fields[0].key);
PW_TEST_EXPECT_EQ("", fields[0].value);
});
PW_CONSTEXPR_TEST(ParseFields, EmptyKey, {
std::array<Field, 1> fields;
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"■♦value",
[&fields, &fields_parsed](std::string_view key, std::string_view val) {
fields[fields_parsed++] = {key, val};
});
PW_TEST_EXPECT_OK(result.status());
PW_TEST_ASSERT_EQ(1u, result.size());
PW_TEST_ASSERT_EQ(1u, fields_parsed);
PW_TEST_EXPECT_EQ("", fields[0].key);
PW_TEST_EXPECT_EQ("value", fields[0].value);
});
PW_CONSTEXPR_TEST(ParseFields, CustomSeparators, {
std::array<Field, 2> fields;
size_t fields_parsed = 0;
StatusWithSize result = ParseFields(
"$key1:value1$key2:value2",
[&fields, &fields_parsed](std::string_view key, std::string_view val) {
fields[fields_parsed++] = {key, val};
},
"$",
":");
PW_TEST_EXPECT_OK(result.status());
PW_TEST_ASSERT_EQ(2u, result.size());
PW_TEST_ASSERT_EQ(2u, fields_parsed);
PW_TEST_EXPECT_EQ("key1", fields[0].key);
PW_TEST_EXPECT_EQ("value1", fields[0].value);
PW_TEST_EXPECT_EQ("key2", fields[1].key);
PW_TEST_EXPECT_EQ("value2", fields[1].value);
});
} // namespace