blob: d33c3c83bede84f72f445cb28a4f32499db7d4d9 [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.
"""Runs Python-based data-driven tests for detokenize."""
import io
from pw_build.generated_tests import TestGenerator, PyTest, Context, main
from pw_tokenizer import tokens
from pw_tokenizer.detokenize import Detokenizer
from detokenize_test_cases import (
TEST_CASES,
OPTIONALLY_TOKENIZED_TEST_CASES,
WITH_ARGS_SUCCESSFUL_CASES_BINARY,
WITH_ARGS_STAR_CASES_BINARY,
WITH_ARGS_PERCENT_G_CASES_BINARY,
WITH_ARGS_PERCENT_E_CASES_BINARY,
WITH_COLLISIONS_CASES_BINARY,
TEST_DATABASE,
DATA_WITH_ARGUMENTS,
DATA_WITH_COLLISIONS,
)
import data_driven_detokenize_test_cc as cc
import data_driven_detokenize_test_java as java
import data_driven_detokenize_test_rust as rust
_BASIC_TESTS = TestGenerator(
TEST_CASES,
cc_test=cc.BASIC_TESTS,
java_test=java.BASIC_TESTS,
rust_test=rust.BASIC_TESTS,
)
_OPTIONALLY_TOKENIZED_TESTS = TestGenerator(
OPTIONALLY_TOKENIZED_TEST_CASES,
cc_test=cc.OPTIONALLY_TOKENIZED_TESTS,
java_test=java.OPTIONALLY_TOKENIZED_TESTS,
rust_test=rust.OPTIONALLY_TOKENIZED_TESTS,
)
_WITH_ARGS_BINARY_TESTS = TestGenerator(
WITH_ARGS_SUCCESSFUL_CASES_BINARY,
cc_test=cc.WITH_ARGS_BINARY_TESTS,
java_test=java.WITH_ARGS_BINARY_TESTS,
rust_test=rust.WITH_ARGS_BINARY_TESTS,
)
_WITH_ARGS_STAR_TESTS = TestGenerator(
WITH_ARGS_STAR_CASES_BINARY,
cc_test=cc.WITH_ARGS_BINARY_TESTS,
java_test=java.WITH_ARGS_BINARY_TESTS,
# TODO: b/523305904 - Support * width and precision in Rust.
rust_test=rust.skip_test('with_args_star_tests'),
)
_WITH_ARGS_PERCENT_G_TESTS = TestGenerator(
WITH_ARGS_PERCENT_G_CASES_BINARY,
cc_test=cc.WITH_ARGS_BINARY_TESTS,
java_test=java.WITH_ARGS_BINARY_TESTS,
# TODO: b/523306892 - Support %g and %G format specifiers in Rust.
rust_test=rust.skip_test('with_args_percent_g_tests'),
)
_WITH_ARGS_PERCENT_E_TESTS = TestGenerator(
WITH_ARGS_PERCENT_E_CASES_BINARY,
cc_test=cc.WITH_ARGS_BINARY_TESTS,
java_test=java.WITH_ARGS_BINARY_TESTS,
# TODO: b/352358580 - Support %e and %E format specifiers in Rust.
rust_test=rust.skip_test('with_args_percent_e_tests'),
)
_WITH_COLLISIONS_TESTS = TestGenerator(
WITH_COLLISIONS_CASES_BINARY,
cc_test=cc.WITH_COLLISIONS_TESTS,
java_test=java.WITH_COLLISIONS_TESTS,
rust_test=rust.WITH_COLLISIONS_TESTS,
)
def _define_py_test_text(detokenizer: Detokenizer, ctx: Context) -> PyTest:
"""Defines a Python detokenizer test for text data."""
data, expected = ctx.test_case
def test(self) -> None:
self.assertEqual(detokenizer.detokenize_text(data), expected)
return test
def _define_py_test_binary(detokenizer: Detokenizer, ctx: Context) -> PyTest:
"""Defines a Python detokenizer test for data."""
data, expected = ctx.test_case
def test(self) -> None:
result = detokenizer.detokenize(data).best_result()
if result is None:
self.assertEqual(
data.decode(errors='ignore'), expected, f'Detokenizing {data}'
)
else:
self.assertEqual(result.value, expected, f'Detokenizing {data}')
return test
DetokenizeTest = _BASIC_TESTS.python_tests(
'DetokenizeTest',
lambda ctx: _define_py_test_text(
Detokenizer(
tokens.Database(tokens.parse_binary(io.BytesIO(TEST_DATABASE)))
),
ctx,
),
)
DetokenizeOptionalTest = _OPTIONALLY_TOKENIZED_TESTS.python_tests(
'DetokenizeOptionalTest',
lambda ctx: _define_py_test_binary(
Detokenizer(
tokens.Database(tokens.parse_binary(io.BytesIO(TEST_DATABASE)))
),
ctx,
),
)
DetokenizeWithArgsBinTest = _WITH_ARGS_BINARY_TESTS.python_tests(
'DetokenizeWithArgsBinTest',
lambda ctx: _define_py_test_binary(
Detokenizer(
tokens.Database(
tokens.parse_binary(io.BytesIO(DATA_WITH_ARGUMENTS))
)
),
ctx,
),
)
DetokenizeWithArgsStarTest = _WITH_ARGS_STAR_TESTS.python_tests(
'DetokenizeWithArgsStarTest',
lambda ctx: _define_py_test_binary(
Detokenizer(
tokens.Database(
tokens.parse_binary(io.BytesIO(DATA_WITH_ARGUMENTS))
)
),
ctx,
),
)
DetokenizeWithArgsPercentGTest = _WITH_ARGS_PERCENT_G_TESTS.python_tests(
'DetokenizeWithArgsPercentGTest',
lambda ctx: _define_py_test_binary(
Detokenizer(
tokens.Database(
tokens.parse_binary(io.BytesIO(DATA_WITH_ARGUMENTS))
)
),
ctx,
),
)
DetokenizeWithArgsPercentETest = _WITH_ARGS_PERCENT_E_TESTS.python_tests(
'DetokenizeWithArgsPercentETest',
lambda ctx: _define_py_test_binary(
Detokenizer(
tokens.Database(
tokens.parse_binary(io.BytesIO(DATA_WITH_ARGUMENTS))
)
),
ctx,
),
)
DetokenizeWithCollisionsTest = _WITH_COLLISIONS_TESTS.python_tests(
'DetokenizeWithCollisionsTest',
lambda ctx: _define_py_test_binary(
Detokenizer(
tokens.Database(
tokens.parse_binary(io.BytesIO(DATA_WITH_COLLISIONS))
)
),
ctx,
),
)
if __name__ == '__main__':
main(
_BASIC_TESTS,
_OPTIONALLY_TOKENIZED_TESTS,
_WITH_ARGS_BINARY_TESTS,
_WITH_ARGS_STAR_TESTS,
_WITH_ARGS_PERCENT_G_TESTS,
_WITH_ARGS_PERCENT_E_TESTS,
_WITH_COLLISIONS_TESTS,
)