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.

135 lines
3.6 KiB

  1. from __future__ import absolute_import
  2. import sys
  3. from unittest import TestCase, main
  4. from lark import Lark, Tree, Transformer
  5. from lark.lexer import Lexer, Token
  6. import lark.lark as lark_module
  7. try:
  8. from StringIO import StringIO
  9. except ImportError:
  10. from io import BytesIO as StringIO
  11. import tempfile, os
  12. class MockFile(StringIO):
  13. def close(self):
  14. pass
  15. def __enter__(self):
  16. return self
  17. def __exit__(self, *args):
  18. pass
  19. class MockFS:
  20. def __init__(self):
  21. self.files = {}
  22. def open(self, name, mode=None):
  23. if name not in self.files:
  24. f = self.files[name] = MockFile()
  25. else:
  26. f = self.files[name]
  27. f.seek(0)
  28. return f
  29. def exists(self, name):
  30. return name in self.files
  31. class CustomLexer(Lexer):
  32. def __init__(self, lexer_conf):
  33. pass
  34. def lex(self, data):
  35. for obj in data:
  36. yield Token('A', obj)
  37. class TestT(Transformer):
  38. def add(self, children):
  39. return sum(children if isinstance(children, list) else children.children)
  40. def NUM(self, token):
  41. return int(token)
  42. def append_zero(t):
  43. return t.update(value=t.value + '0')
  44. class TestCache(TestCase):
  45. def setUp(self):
  46. pass
  47. def test_simple(self):
  48. g = '''start: "a"'''
  49. fn = "bla"
  50. fs = lark_module.FS
  51. mock_fs = MockFS()
  52. try:
  53. lark_module.FS = mock_fs
  54. Lark(g, parser='lalr', cache=fn)
  55. assert fn in mock_fs.files
  56. parser = Lark(g, parser='lalr', cache=fn)
  57. assert parser.parse('a') == Tree('start', [])
  58. mock_fs.files = {}
  59. assert len(mock_fs.files) == 0
  60. Lark(g, parser='lalr', cache=True)
  61. assert len(mock_fs.files) == 1
  62. parser = Lark(g, parser='lalr', cache=True)
  63. assert parser.parse('a') == Tree('start', [])
  64. parser = Lark(g + ' "b"', parser='lalr', cache=True)
  65. assert len(mock_fs.files) == 2
  66. assert parser.parse('ab') == Tree('start', [])
  67. parser = Lark(g, parser='lalr', cache=True)
  68. assert parser.parse('a') == Tree('start', [])
  69. # Test with custom lexer
  70. mock_fs.files = {}
  71. parser = Lark(g, parser='lalr', lexer=CustomLexer, cache=True)
  72. parser = Lark(g, parser='lalr', lexer=CustomLexer, cache=True)
  73. assert len(mock_fs.files) == 1
  74. assert parser.parse('a') == Tree('start', [])
  75. # Test options persistence
  76. mock_fs.files = {}
  77. Lark(g, parser="lalr", debug=True, cache=True)
  78. parser = Lark(g, parser="lalr", debug=True, cache=True)
  79. assert parser.options.options['debug']
  80. # Test inline transformer (tree-less) & lexer_callbacks
  81. mock_fs.files = {}
  82. g = """
  83. start: add+
  84. add: NUM "+" NUM
  85. NUM: /\d+/
  86. %ignore " "
  87. """
  88. text = "1+2 3+4"
  89. expected = Tree('start', [30, 70])
  90. parser = Lark(g, parser='lalr', transformer=TestT(), cache=True, lexer_callbacks={'NUM': append_zero})
  91. res0 = parser.parse(text)
  92. parser = Lark(g, parser='lalr', transformer=TestT(), cache=True, lexer_callbacks={'NUM': append_zero})
  93. assert len(mock_fs.files) == 1
  94. res1 = parser.parse(text)
  95. res2 = TestT().transform(Lark(g, parser="lalr", cache=True, lexer_callbacks={'NUM': append_zero}).parse(text))
  96. assert res0 == res1 == res2 == expected
  97. finally:
  98. lark_module.FS = fs
  99. if __name__ == '__main__':
  100. main()