blob: 48b2d74bf6367c8ce87afce0b34d1be27ccac2e3 [file]
# Copyright 2026 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.
"""Generates C++ data-driven detokenizer test code."""
from typing import Iterator
from pw_build.generated_tests import Context, cc_string
import detokenize_test_cases as shared
_CPP_HEADER = """
#include "pw_tokenizer/detokenize.h"
#include <string_view>
#include "pw_bytes/array.h"
#include "pw_tokenizer_private/printf_support.h"
#include "pw_unit_test/framework.h"
namespace {
using namespace std::literals::string_view_literals;
"""
_CPP_FOOTER = """
} // namespace
"""
_CPP_DATABASE_DEFS = f"""
constexpr char kTestDatabaseRaw[] = {cc_string(shared.TEST_DATABASE)};
constexpr pw::tokenizer::TokenDatabase kTestDatabase =
pw::tokenizer::TokenDatabase::Create<kTestDatabaseRaw>();
constexpr char kDataWithArgumentsRaw[] =
{cc_string(shared.DATA_WITH_ARGUMENTS)};
constexpr pw::tokenizer::TokenDatabase kDataWithArguments =
pw::tokenizer::TokenDatabase::Create<kDataWithArgumentsRaw>();
constexpr char kDataWithCollisionsRaw[] =
{cc_string(shared.DATA_WITH_COLLISIONS)};
constexpr pw::tokenizer::TokenDatabase kDataWithCollisions =
pw::tokenizer::TokenDatabase::Create<kDataWithCollisionsRaw>();
"""
def _cpp_test_text(ctx: Context) -> Iterator[str]:
data, expected = ctx.test_case
yield f"""\
TEST(DetokenizeTest, {ctx.cc_name()}) {{
const pw::tokenizer::Detokenizer detok(kTestDatabase);
EXPECT_EQ(detok.DetokenizeText({cc_string(data)}sv), {cc_string(expected)});
}}"""
def _cpp_test_optional(ctx: Context) -> Iterator[str]:
data, expected = ctx.test_case
yield f"""\
TEST(DetokenizeOptionalTest, {ctx.cc_name()}) {{
const pw::tokenizer::Detokenizer detok(kTestDatabase);
constexpr std::string_view data = {cc_string(data)}sv;
EXPECT_EQ(
detok.DecodeOptionallyTokenizedData(pw::as_bytes(pw::span(data))),
{cc_string(expected)}
);
}}"""
def _cpp_test_with_args(ctx: Context) -> Iterator[str]:
data, expected = ctx.test_case
yield f"""\
TEST(DetokenizeWithArgsBinTest, {ctx.cc_name()}) {{
const pw::tokenizer::Detokenizer detok(kDataWithArguments);
constexpr std::string_view data = {cc_string(data)}sv;
const auto result = detok.Detokenize(pw::as_bytes(pw::span(data)));
if (pw::tokenizer::test::FormatIsSupported(detok, data)) {{
EXPECT_EQ(result.BestString(), {cc_string(expected)});
}} else {{
EXPECT_NE(result.BestString(), {cc_string(expected)});
}}
}}"""
def _cpp_test_with_collisions(ctx: Context) -> Iterator[str]:
data, expected = ctx.test_case
yield f"""\
TEST(DetokenizeWithCollisionsTest, {ctx.cc_name()}) {{
const pw::tokenizer::Detokenizer detok(kDataWithCollisions);
constexpr std::string_view data = {cc_string(data)}sv;
EXPECT_EQ(
detok.Detokenize(pw::as_bytes(pw::span(data))).BestString(),
{cc_string(expected)}
);
}}"""
BASIC_TESTS = (_cpp_test_text, _CPP_HEADER + _CPP_DATABASE_DEFS, '')
OPTIONALLY_TOKENIZED_TESTS = (_cpp_test_optional, '', '')
WITH_ARGS_BINARY_TESTS = (_cpp_test_with_args, '', '')
WITH_COLLISIONS_TESTS = (_cpp_test_with_collisions, '', _CPP_FOOTER)