"""Tests for SORE → GBNF converter.""" import pytest from bex.gbnf import to_gbnf, to_gbnf_with_rules class TestToGBNF: def test_literal(self): assert to_gbnf('mockk') == 'root ::= "mockk"' def test_concat(self): assert to_gbnf('raise.ValueError') == 'root ::= "raise" "ValueError"' def test_plus_group(self): assert to_gbnf('(append)+') == 'root ::= "append"+' def test_plus_concat(self): assert to_gbnf('raise.(ValueError)+') == 'root ::= "raise" "ValueError"+' def test_nested_optional_plus(self): assert to_gbnf('assertEquals.(of.(assertFailsWith)?)+') == \ 'root ::= "assertEquals" ("of" "assertFailsWith"?)+' def test_long_concat(self): assert to_gbnf('filesIn.filter.contains.assertTrue.(hasImport)+') == \ 'root ::= "filesIn" "filter" "contains" "assertTrue" "hasImport"+' def test_simple_concat(self): assert to_gbnf('trim.lowercase.(warn)+') == 'root ::= "trim" "lowercase" "warn"+' def test_flat_concat(self): assert to_gbnf('DoclingConfig.assertThatThrownBy.validateCriticalSettings.isInstanceOf.hasMessageContaining') == \ 'root ::= "DoclingConfig" "assertThatThrownBy" "validateCriticalSettings" "isInstanceOf" "hasMessageContaining"' def test_simple_plus(self): assert to_gbnf('(abort)+') == 'root ::= "abort"+' def test_concat_with_plus(self): assert to_gbnf('return.(url_for)+') == 'root ::= "return" "url_for"+' def test_star(self): assert to_gbnf('(foo)*') == 'root ::= "foo"*' def test_optional(self): assert to_gbnf('(bar)?') == 'root ::= "bar"?' class TestToGBNFWithRules: def test_named_rule(self): result = to_gbnf_with_rules('raise.(ValueError)+', name='my-pattern') assert result == 'my-pattern ::= "raise" "ValueError"+' def test_default_name(self): result = to_gbnf_with_rules('mockk') assert result == 'root ::= "mockk"' def test_nested(self): result = to_gbnf_with_rules('assertEquals.(of.(assertFailsWith)?)+') assert result == 'root ::= "assertEquals" ("of" "assertFailsWith"?)+'