19035812c3
Aggiunge il modulo `multi_swarm.protocol` con la grammatica del DSL di strategia (15 verbi: 4 azioni, 3 logici, 3 comparatori, 4 dati, `when` e `strategy`) e un parser che produce un AST tipizzato (Strategy/Rule/ Node). Lessing delegato a sexpdata, validazione del set di verbi e forma `(when <cond> <action>)` gestita dal parser. Sollevata ParseError su top-level malformato, strategia vuota, verbi sconosciuti o azioni non terminali. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
48 lines
1.2 KiB
Python
48 lines
1.2 KiB
Python
import pytest
|
|
|
|
from multi_swarm.protocol.grammar import VERBS
|
|
from multi_swarm.protocol.parser import ParseError, parse_strategy
|
|
|
|
|
|
def test_grammar_has_15_verbs():
|
|
assert len(VERBS) == 15
|
|
|
|
|
|
def test_parse_simple_strategy():
|
|
src = "(strategy (when (gt (indicator rsi 14) 70.0) (entry-short)))"
|
|
ast = parse_strategy(src)
|
|
assert ast.kind == "strategy"
|
|
assert len(ast.rules) == 1
|
|
rule = ast.rules[0]
|
|
assert rule.kind == "when"
|
|
assert rule.condition.kind == "gt"
|
|
assert rule.action.kind == "entry-short"
|
|
|
|
|
|
def test_parse_multiple_rules():
|
|
src = """
|
|
(strategy
|
|
(when (gt (indicator rsi 14) 70.0) (entry-short))
|
|
(when (lt (indicator rsi 14) 30.0) (entry-long)))
|
|
"""
|
|
ast = parse_strategy(src)
|
|
assert len(ast.rules) == 2
|
|
|
|
|
|
def test_parse_unknown_verb_raises():
|
|
src = "(strategy (when (frobnicate 1 2) (entry-long)))"
|
|
with pytest.raises(ParseError):
|
|
parse_strategy(src)
|
|
|
|
|
|
def test_parse_malformed_raises():
|
|
src = "(strategy (when"
|
|
with pytest.raises(ParseError):
|
|
parse_strategy(src)
|
|
|
|
|
|
def test_parse_empty_strategy_raises():
|
|
src = "(strategy)"
|
|
with pytest.raises(ParseError):
|
|
parse_strategy(src)
|