1
0
mirror of https://github.com/MarkParker5/STARK.git synced 2026-04-28 19:34:24 +02:00
Files
STARK/tests/test_patterns/test_pattern_parameters.py
2025-11-25 02:10:21 +01:00

126 lines
4.2 KiB
Python

import pytest
from stark.core import Pattern
from stark.core.parsing import ParseError
from stark.core.patterns import rules
from stark.core.types import Object, String, Word
from stark.general.classproperty import classproperty
word = rf"[{rules.alphanumerics}]+"
words = rf"[{rules.alphanumerics}\s]*"
class ExtraParameterInPattern(Object):
word1: Word
word2: Word
@classproperty
def pattern(cls) -> Pattern:
return Pattern("$word1:Word $word2:Word $word3:Word")
async def test_typed_parameters():
p = Pattern("lorem $name:Word dolor")
assert pattern_parser.parameter_types_by_name[p.parameters["name"].type_name].type == Word
# assert pattern_parser._compile_pattern(p) == rf"lorem (?P<name>{word}) dolor" # compiled is not available
m = await pattern_parser.match(p, "lorem ipsum dolor")
assert m
assert m[0].substring == "lorem ipsum dolor"
assert m[0].parameters["name"] == Word("ipsum")
assert not await pattern_parser.match(p, "lorem ipsum foo dolor")
p = Pattern("lorem $name:String dolor")
assert pattern_parser.parameter_types_by_name[p.parameters["name"].type_name].type == String
m = await pattern_parser.match(p, "lorem ipsum foo bar dolor")
assert m
assert m[0].substring == "lorem ipsum foo bar dolor"
assert m[0].parameters["name"] == String("ipsum foo bar")
async def test_middle_optional_parameter():
p = Pattern("lorem $name:Word? dolor")
# print(p.compiled)
assert pattern_parser.parameter_types_by_name[p.parameters["name"].type_name].type == Word
assert await pattern_parser.match(p, "lorem dolor")
# assert await pattern_parser.match(p, 'lorem dolor')
m2 = await pattern_parser.match(p, "lorem ipsum dolor")
assert m2
assert m2[0].parameters["name"] == Word("ipsum")
async def test_trailing_optional_parameter():
p = Pattern("lorem $name:Word?")
assert pattern_parser.parameter_types_by_name[p.parameters["name"].type_name].type == Word
assert await pattern_parser.match(p, "lorem ")
# assert await pattern_parser.match(p, 'lorem')
m = await pattern_parser.match(p, "lorem ipsum")
assert m
assert m[0].parameters["name"] == Word("ipsum")
async def test_optional_group():
p = Pattern("lorem( ipsum $name:Word)? dolor")
# assert p.parameters == {('name', Word, True)}
assert pattern_parser.parameter_types_by_name[p.parameters["name"].type_name].type == Word
assert await pattern_parser.match(p, "lorem dolor")
m2 = await pattern_parser.match(p, "lorem ipsum variable dolor")
assert m2
assert m2[0].parameters["name"] == Word("variable")
class TwoWords(Object):
word1: Word
word2: Word
@classproperty
def pattern(cls) -> Pattern:
return Pattern("$word1:Word $word2:Word")
from stark.core.parsing import PatternParser
pattern_parser = PatternParser()
pattern_parser.register_parameter_type(TwoWords)
async def test_parameter_type_duplicate():
# test fix for re.error: redefinition of group name
p = Pattern("hello $name:TwoWords and $name2:TwoWords")
assert pattern_parser.parameter_types_by_name[p.parameters["name"].type_name].type == TwoWords
m = await pattern_parser.match(p, "hello John Galt and Alice Smith")
assert m
class OOWordSimple2(Word):
async def did_parse(self, from_string: str) -> str:
if "oo" not in from_string:
raise ParseError("OOWord must contain 'oo'")
self.value = from_string
return from_string
from stark.core.parsing import PatternParser
pattern_parser.register_parameter_type(OOWordSimple2)
@pytest.mark.parametrize(
"pattern_str, input_str, expected_params",
[
("$name:OOWordSimple2 ?* $name2:OOWordSimple2", "Joohn Janoo", {"name": "Joohn", "name2": "Janoo"}),
("$name:OOWordSimple2 ?* $name2:OOWordSimple2", "Joohn and Janoo", {"name": "Joohn", "name2": "Janoo"}),
("$name:OOWordSimple2 ?** $name2:OOWordSimple2", "Joohn and famous Janoo", {"name": "Joohn", "name2": "Janoo"}),
],
)
async def test_extra_simple_patterns_extra_words(pattern_str, input_str, expected_params):
p = Pattern(pattern_str)
m = await pattern_parser.match(p, input_str)
assert m
assert {k: v.value for k, v in m[0].parameters.items()} == expected_params