This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
5.0 KiB

  1. from __future__ import absolute_import
  2. import unittest
  3. from unittest import TestCase
  4. import copy
  5. import pickle
  6. import functools
  7. from lark.tree import Tree
  8. from lark.visitors import Transformer, Interpreter, visit_children_decor, v_args, Discard
  9. class TestTrees(TestCase):
  10. def setUp(self):
  11. self.tree1 = Tree('a', [Tree(x, y) for x, y in zip('bcd', 'xyz')])
  12. def test_deepcopy(self):
  13. assert self.tree1 == copy.deepcopy(self.tree1)
  14. def test_pickle(self):
  15. s = copy.deepcopy(self.tree1)
  16. data = pickle.dumps(s)
  17. assert pickle.loads(data) == s
  18. def test_iter_subtrees(self):
  19. expected = [Tree('b', 'x'), Tree('c', 'y'), Tree('d', 'z'),
  20. Tree('a', [Tree('b', 'x'), Tree('c', 'y'), Tree('d', 'z')])]
  21. nodes = list(self.tree1.iter_subtrees())
  22. self.assertEqual(nodes, expected)
  23. def test_iter_subtrees_topdown(self):
  24. expected = [Tree('a', [Tree('b', 'x'), Tree('c', 'y'), Tree('d', 'z')]),
  25. Tree('b', 'x'), Tree('c', 'y'), Tree('d', 'z')]
  26. nodes = list(self.tree1.iter_subtrees_topdown())
  27. self.assertEqual(nodes, expected)
  28. def test_interp(self):
  29. t = Tree('a', [Tree('b', []), Tree('c', []), 'd'])
  30. class Interp1(Interpreter):
  31. def a(self, tree):
  32. return self.visit_children(tree) + ['e']
  33. def b(self, tree):
  34. return 'B'
  35. def c(self, tree):
  36. return 'C'
  37. self.assertEqual(Interp1().visit(t), list('BCde'))
  38. class Interp2(Interpreter):
  39. @visit_children_decor
  40. def a(self, values):
  41. return values + ['e']
  42. def b(self, tree):
  43. return 'B'
  44. def c(self, tree):
  45. return 'C'
  46. self.assertEqual(Interp2().visit(t), list('BCde'))
  47. class Interp3(Interpreter):
  48. def b(self, tree):
  49. return 'B'
  50. def c(self, tree):
  51. return 'C'
  52. self.assertEqual(Interp3().visit(t), list('BCd'))
  53. def test_transformer(self):
  54. t = Tree('add', [Tree('sub', [Tree('i', ['3']), Tree('f', ['1.1'])]), Tree('i', ['1'])])
  55. class T(Transformer):
  56. i = v_args(inline=True)(int)
  57. f = v_args(inline=True)(float)
  58. sub = lambda self, values: values[0] - values[1]
  59. def add(self, values):
  60. return sum(values)
  61. res = T().transform(t)
  62. self.assertEqual(res, 2.9)
  63. @v_args(inline=True)
  64. class T(Transformer):
  65. i = int
  66. f = float
  67. sub = lambda self, a, b: a-b
  68. def add(self, a, b):
  69. return a + b
  70. res = T().transform(t)
  71. self.assertEqual(res, 2.9)
  72. @v_args(inline=True)
  73. class T(Transformer):
  74. i = int
  75. f = float
  76. from operator import sub, add
  77. res = T().transform(t)
  78. self.assertEqual(res, 2.9)
  79. def test_vargs(self):
  80. @v_args()
  81. class MyTransformer(Transformer):
  82. @staticmethod
  83. def integer(args):
  84. return 1 # some code here
  85. @classmethod
  86. def integer2(cls, args):
  87. return 2 # some code here
  88. hello = staticmethod(lambda args: 'hello')
  89. x = MyTransformer().transform( Tree('integer', [2]))
  90. self.assertEqual(x, 1)
  91. x = MyTransformer().transform( Tree('integer2', [2]))
  92. self.assertEqual(x, 2)
  93. x = MyTransformer().transform( Tree('hello', [2]))
  94. self.assertEqual(x, 'hello')
  95. def test_vargs_override(self):
  96. t = Tree('add', [Tree('sub', [Tree('i', ['3']), Tree('f', ['1.1'])]), Tree('i', ['1'])])
  97. @v_args(inline=True)
  98. class T(Transformer):
  99. i = int
  100. f = float
  101. sub = lambda self, a, b: a-b
  102. not_a_method = {'other': 'stuff'}
  103. @v_args(inline=False)
  104. def add(self, values):
  105. return sum(values)
  106. res = T().transform(t)
  107. self.assertEqual(res, 2.9)
  108. def test_partial(self):
  109. tree = Tree("start", [Tree("a", ["test1"]), Tree("b", ["test2"])])
  110. def test(prefix, s, postfix):
  111. return prefix + s.upper() + postfix
  112. @v_args(inline=True)
  113. class T(Transformer):
  114. a = functools.partial(test, "@", postfix="!")
  115. b = functools.partial(lambda s: s + "!")
  116. res = T().transform(tree)
  117. assert res.children == ["@TEST1!", "test2!"]
  118. def test_discard(self):
  119. class MyTransformer(Transformer):
  120. def a(self, args):
  121. return 1 # some code here
  122. def b(cls, args):
  123. raise Discard()
  124. t = Tree('root', [
  125. Tree('b', []),
  126. Tree('a', []),
  127. Tree('b', []),
  128. Tree('c', []),
  129. Tree('b', []),
  130. ])
  131. t2 = Tree('root', [1, Tree('c', [])])
  132. x = MyTransformer().transform( t )
  133. self.assertEqual(x, t2)
  134. if __name__ == '__main__':
  135. unittest.main()