def test_repeated_layouts(self): class Block(Node): pass def space_layout(dispatcher, node, before, after, prev): yield SimpleChunk(' ') def newline_layout(dispatcher, node, before, after, prev): yield SimpleChunk('n') dispatcher = Dispatcher( definitions={ 'Node': (Space, ), 'Block': (JoinAttr(Iter(), value=(Newline, )), ) }, token_handler=None, # not actually produced layout_handlers={ Space: space_layout, Newline: newline_layout, # drop the subsequent space (Newline, Space): newline_layout, }, deferrable_handlers={}, ) n0 = Block([]) self.assertEqual('', ''.join(c.text for c in walk(dispatcher, n0))) n1 = Block([Node([])] * 1) self.assertEqual(' ', ''.join(c.text for c in walk(dispatcher, n1))) n2 = Block([Node([])] * 2) self.assertEqual(' n', ''.join(c.text for c in walk(dispatcher, n2))) n3 = Block([Node([])] * 3) self.assertEqual(' nn', ''.join(c.text for c in walk(dispatcher, n3)))
def test_nested_layouts(self): def simple_layout_space(dispatcher, node, before, after, prev): yield SimpleChunk(' ') def nested_layout(dispatcher, node, before, after, prev): yield SimpleChunk('?') def noop(*a, **kw): return yield # pragma: no cover dispatcher = Dispatcher( definitions={'Node': ( Space, JoinAttr(Iter(), value=(Space, )), )}, token_handler=noop, layout_handlers={ Space: simple_layout_space, (Space, Space): noop, ((Space, Space), Space): nested_layout, }, deferrable_handlers={}, ) n0 = Node([]) self.assertEqual(' ', ''.join(c.text for c in walk(dispatcher, n0))) n1 = Node([n0]) self.assertEqual('', ''.join(c.text for c in walk(dispatcher, n1))) n2 = Node([n1, n0]) self.assertEqual('?', ''.join(c.text for c in walk(dispatcher, n2)))
def test_join_attr_issue_36(self): # JoinAttr defined with parameter `value=None` resulted in # infinite recursion due to the walker will assume that no rule # is provided, triggering rule lookup which would repeat the # work that was done. class Block(Node): pass token_handler, layout_handlers, deferrable_handlers, declared_vars = ( setup_handlers(self)) dispatcher = Dispatcher( definitions={ 'Block': (JoinAttr(Iter(), value=None), ), 'Node': (Text(value='', ), ), }, token_handler=token_handler, layout_handlers={}, deferrable_handlers={}, ) nodes = Block([Node([])] * 3) self.assertEqual(3, len(list(walk(dispatcher, nodes))))
from calmjs.parse.unparsers.walker import Dispatcher from calmjs.parse.unparsers.walker import walk from calmjs.parse.ruletypes import ( Attr, JoinAttr, Text, Operator, Space, Newline, Iter, Declare, Resolve, ) SimpleChunk = namedtuple('SimpleChunk', ['text']) children_newline = JoinAttr(Iter(), value=(Newline, )) children_comma = JoinAttr(Iter(), value=( Text(value=','), Space, )) def setup_handlers(testcase): # only provide the bare minimum needed for the tests here. testcase.replacement = {} testcase.tokens_handled = [] testcase.layouts_handled = [] declared_vars = [] def replace(dispatcher, node): return testcase.replacement.get(node.value, node.value)
'Array': ( CommentsAttr(), Text(value='['), ElisionJoinAttr('items', value=(Space,)), Text(value=']'), ), 'Elision': ( CommentsAttr(), ElisionToken(attr='value', value=','), ), 'This': ( CommentsAttr(), Text(value='this'), ), 'Comments': ( JoinAttr(Iter(), value=()), ), 'LineComment': ( Attr(LineComment()), Newline, ), 'BlockComment': ( Attr(BlockComment()), Newline, ), } class Unparser(BaseUnparser): def __init__( self, definitions=definitions,