def test_list_node_generate(node: nodes.ListNode, ctx: dict, expected_output: str, want_err: Optional[Exception]) -> None: if want_err: with pytest.raises(want_err): node.generate(ctx=Context(ctx)) else: assert expected_output == node.generate(ctx=Context(ctx))
def test_placeholder_node_generate( node: nodes.PlaceholderNode, ctx: dict, expected_output: str, want_err: Optional[Exception], ) -> None: if want_err is not None: with pytest.raises(want_err): node.generate(ctx=Context(ctx) if ctx is not None else None) else: assert expected_output == node.generate(ctx=Context(ctx))
def generate(self, ctx: Context = None): # type: ignore """ Substitutes the placeholder. Args: ctx (Optional[Context]): The generation context. Returns: A randomly selected value from the corresponding context key. """ if ctx is None: raise RuntimeError( f"could not get value for placeholder [{self.key}] - no context provided" ) try: val = ctx.get(self.key) except KeyError: raise RuntimeError( f"could not get value for placeholder [{self.key}] - key is missing" ) if not val: return "" return sub_punctuation(LiteralNode(random.choice(val))).generate()
def test_get_flat_values(): c = Context({ "hello": "world", "a": 42, "b": True, "c": 42.42, "rdm": ["a", "s", "d", "f"] }) assert ["world"] == c.get("hello") assert ["42"] == c.get("a") assert ["True"] == c.get("b") assert ["42.42"] == c.get("c") assert ["a", "s", "d", "f"] == c.get("rdm") with pytest.raises(KeyError): c.get("unknown")
def test_get_nested_values(): c = Context({"a": {"b": {"c": [18, 19], "a": "world"}, "a": "hello"}}) assert ["hello"] == c.get("a.a") assert ["world"] == c.get("a.b.a") assert ["{'c': [18, 19], 'a': 'world'}"] == c.get("a.b") assert ["18", "19"] == c.get("a.b.c")
def generate(self, entity_name: str, ctx: dict = None) -> str: # type: ignore """ Generates a value for a specific entity. Args: entity_name (str): The name of the entity to generate. ctx (Optional[dict]): The generation context. Returns: The generated entity. """ new_context = Context(ctx) if ctx else None return self.entities[entity_name].generate(ctx=new_context).strip()
def make(src: str, bind_ctx: dict = None) -> nodes.Grammar: """ Parse & optimize a grammar from source code. Args: src (str): The grammar source. bind_ctx (Optional[dict]): The context to bind to the grammar. Returns: An optimized grammar object. """ ctx = Context(bind_ctx) if bind_ctx else None p = DescentParser(src) return optimize(p.grammar(), ctx)
def test_context_initialize_with_none(): c = Context() assert {} == c.ctx
def test_repeat_node_generate(node: nodes.RepeatNode, ctx: dict, expected_output: str) -> None: assert expected_output == node.generate(ctx=Context(ctx))
def test_any_node_generate(node: nodes.AnyNode, ctx: dict, value_set: Set[str]) -> None: for i in range(1000): assert node.generate(ctx=Context(ctx)) in value_set
], ) def test_sub_punctuation(input_node: nodes.LiteralNode, expected_output: nodes.Node) -> None: assert nodes.sub_punctuation(input_node) == expected_output @pytest.mark.parametrize( "input_node,input_ctx,expected_node", [ ( nodes.ConditionNode( (nodes.PlaceholderNode("a"), nodes.PlaceholderNode("b")), nodes.LiteralNode("a"), ), Context({}), nodes.ConditionNode( (nodes.PlaceholderNode("a"), nodes.PlaceholderNode("b")), nodes.LiteralNode("a"), ), ), ( nodes.ConditionNode( (nodes.PlaceholderNode("a"), nodes.PlaceholderNode("b")), nodes.LiteralNode("a"), ), Context({ "a": "asdf", "b": "asdf" }), nodes.LiteralNode("a"),
) def test_optimizer_visit_any_node(node: nodes.Node, expected: nodes.Node) -> None: o = Optimizer({}, {}) assert expected == o.visit_any_node(node) @pytest.mark.parametrize( "node,ctx,expected", [ ( nodes.ConditionNode( (nodes.PlaceholderNode("a"), nodes.PlaceholderNode("b")), nodes.LiteralNode("a"), ), Context({}), nodes.ConditionNode( (nodes.PlaceholderNode("a"), nodes.PlaceholderNode("b")), nodes.LiteralNode("a"), ), ), ( nodes.ConditionNode( (nodes.PlaceholderNode("a"), nodes.PlaceholderNode("b")), nodes.LiteralNode("a"), ), Context({ "a": "asdf", "b": "asdf" }), nodes.LiteralNode("a"),