diff options
Diffstat (limited to 'tests/test_declarative_parser.py')
-rw-r--r-- | tests/test_declarative_parser.py | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/tests/test_declarative_parser.py b/tests/test_declarative_parser.py new file mode 100644 index 0000000..a5061cb --- /dev/null +++ b/tests/test_declarative_parser.py @@ -0,0 +1,211 @@ +from typing import List, TypedDict, NotRequired, Annotated, Union, Mapping + +import pytest + +from debputy.highlevel_manifest import PackageTransformationDefinition +from debputy.manifest_parser.base_types import DebputyParsedContent, TypeMapping +from debputy.manifest_parser.declarative_parser import ( + DebputyParseHint, + ParserGenerator, +) +from debputy.manifest_parser.mapper_code import type_mapper_str2package +from debputy.manifest_parser.parser_data import ParserContextData +from debputy.manifest_parser.util import AttributePath +from debputy.packages import BinaryPackage +from debputy.substitution import NULL_SUBSTITUTION +from tutil import faked_binary_package + + +class TFinalEntity(DebputyParsedContent): + sources: List[str] + install_as: NotRequired[str] + into: NotRequired[List[BinaryPackage]] + recursive: NotRequired[bool] + + +class TSourceEntity(TypedDict): + sources: NotRequired[List[str]] + source: Annotated[NotRequired[str], DebputyParseHint.target_attribute("sources")] + as_: NotRequired[ + Annotated[ + str, + DebputyParseHint.target_attribute("install_as"), + DebputyParseHint.conflicts_with_source_attributes("sources"), + ] + ] + into: NotRequired[Union[BinaryPackage, List[BinaryPackage]]] + recursive: NotRequired[bool] + + +TSourceEntityAltFormat = Union[TSourceEntity, List[str], str] + + +foo_package = faked_binary_package("foo") +context_packages = { + foo_package.name: foo_package, +} +context_package_states = { + p.name: PackageTransformationDefinition( + p, + NULL_SUBSTITUTION, + False, + ) + for p in context_packages.values() +} + + +class TestParserContextData(ParserContextData): + @property + def _package_states(self) -> Mapping[str, PackageTransformationDefinition]: + return context_package_states + + @property + def binary_packages(self) -> Mapping[str, BinaryPackage]: + return context_packages + + +@pytest.fixture +def parser_context(): + return TestParserContextData() + + +@pytest.mark.parametrize( + "source_payload,expected_data,expected_attribute_path,parse_content,source_content", + [ + ( + {"sources": ["foo", "bar"]}, + {"sources": ["foo", "bar"]}, + { + "sources": "sources", + }, + TFinalEntity, + None, + ), + ( + {"sources": ["foo", "bar"], "install-as": "as-value"}, + {"sources": ["foo", "bar"], "install_as": "as-value"}, + {"sources": "sources", "install_as": "install-as"}, + TFinalEntity, + None, + ), + ( + {"sources": ["foo", "bar"], "install-as": "as-value", "into": ["foo"]}, + { + "sources": ["foo", "bar"], + "install_as": "as-value", + "into": [foo_package], + }, + {"sources": "sources", "install_as": "install-as", "into": "into"}, + TFinalEntity, + None, + ), + ( + {"source": "foo", "as": "as-value", "into": ["foo"]}, + { + "sources": ["foo"], + "install_as": "as-value", + "into": [foo_package], + }, + {"sources": "source", "install_as": "as", "into": "into"}, + TFinalEntity, + TSourceEntity, + ), + ( + {"source": "foo", "as": "as-value", "into": ["foo"]}, + { + "sources": ["foo"], + "install_as": "as-value", + "into": [foo_package], + }, + {"sources": "source", "install_as": "as", "into": "into"}, + TFinalEntity, + TSourceEntityAltFormat, + ), + ( + ["foo", "bar"], + { + "sources": ["foo", "bar"], + }, + {"sources": "parse-root"}, + TFinalEntity, + TSourceEntityAltFormat, + ), + ( + "foo", + { + "sources": ["foo"], + }, + {"sources": "parse-root"}, + TFinalEntity, + TSourceEntityAltFormat, + ), + ( + "foo", + { + "sources": ["foo"], + }, + {"sources": "parse-root"}, + TFinalEntity, + str, + ), + ( + ["foo", "bar"], + { + "sources": ["foo", "bar"], + }, + {"sources": "parse-root"}, + TFinalEntity, + List[str], + ), + ( + "foo", + { + "sources": ["foo"], + }, + {"sources": "parse-root"}, + TFinalEntity, + Union[str, List[str]], + ), + ( + ["foo", "bar"], + { + "sources": ["foo", "bar"], + }, + {"sources": "parse-root"}, + TFinalEntity, + Union[str, List[str]], + ), + ( + {"source": "foo", "recursive": True}, + { + "sources": ["foo"], + "recursive": True, + }, + {"sources": "source", "recursive": "recursive"}, + TFinalEntity, + TSourceEntityAltFormat, + ), + ], +) +def test_declarative_parser_ok( + attribute_path: AttributePath, + parser_context: ParserContextData, + source_payload, + expected_data, + expected_attribute_path, + parse_content, + source_content, +): + pg = ParserGenerator() + pg.register_mapped_type(TypeMapping(BinaryPackage, str, type_mapper_str2package)) + parser = pg.parser_from_typed_dict( + parse_content, + source_content=source_content, + ) + data_path = attribute_path["parse-root"] + parsed_data = parser.parse_input( + source_payload, data_path, parser_context=parser_context + ) + assert expected_data == parsed_data + attributes = {k: data_path[k].name for k in expected_attribute_path} + assert attributes == expected_attribute_path |