PageRenderTime 147ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/antlr-3.0/runtime/Python/tests/testbase.py

http://perseph.googlecode.com/
Python | 315 lines | 291 code | 20 blank | 4 comment | 20 complexity | 8560b25d827c7a60bc9f16cb0013553f MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0
  1. import unittest
  2. import imp
  3. import os
  4. import errno
  5. import sys
  6. import glob
  7. import re
  8. from distutils.errors import *
  9. def unlink(path):
  10. try:
  11. os.unlink(path)
  12. except OSError, exc:
  13. if exc.errno != errno.ENOENT:
  14. raise
  15. class BrokenTest(unittest.TestCase.failureException):
  16. def __repr__(self):
  17. name, reason = self.args
  18. return '%s: %s: %s works now' % (
  19. (self.__class__.__name__, name, reason))
  20. def broken(reason, *exceptions):
  21. '''Indicates a failing (or erroneous) test case fails that should succeed.
  22. If the test fails with an exception, list the exception type in args'''
  23. def wrapper(test_method):
  24. def replacement(*args, **kwargs):
  25. try:
  26. test_method(*args, **kwargs)
  27. except exceptions or unittest.TestCase.failureException:
  28. pass
  29. else:
  30. raise BrokenTest(test_method.__name__, reason)
  31. replacement.__doc__ = test_method.__doc__
  32. replacement.__name__ = 'XXX_' + test_method.__name__
  33. replacement.todo = reason
  34. return replacement
  35. return wrapper
  36. dependencyCache = {}
  37. compileErrorCache = {}
  38. # setup java CLASSPATH
  39. if 'CLASSPATH' not in os.environ:
  40. cp = []
  41. baseDir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
  42. libDir = os.path.join(baseDir, 'lib')
  43. jar = os.path.join(libDir, 'stringtemplate-3.0.jar')
  44. if not os.path.isfile(jar):
  45. raise DistutilsFileError(
  46. "Missing file '%s'. Grap it from a distribution package."
  47. % jar,
  48. )
  49. cp.append(jar)
  50. jar = os.path.join(libDir, 'antlr-2.7.7.jar')
  51. if not os.path.isfile(jar):
  52. raise DistutilsFileError(
  53. "Missing file '%s'. Grap it from a distribution package."
  54. % jar,
  55. )
  56. cp.append(jar)
  57. jar = os.path.join(libDir, 'junit-4.2.jar')
  58. if not os.path.isfile(jar):
  59. raise DistutilsFileError(
  60. "Missing file '%s'. Grap it from a distribution package."
  61. % jar,
  62. )
  63. cp.append(jar)
  64. cp.append(os.path.join(baseDir, 'runtime', 'Python', 'build'))
  65. classpath = '-cp "' + ':'.join([os.path.abspath(p) for p in cp]) + '"'
  66. else:
  67. classpath = ''
  68. class ANTLRTest(unittest.TestCase):
  69. def __init__(self, *args, **kwargs):
  70. unittest.TestCase.__init__(self, *args, **kwargs)
  71. self.baseName = os.path.splitext(os.path.basename(sys.modules[self.__module__].__file__))[0]
  72. self.lexerModule = None
  73. self.parserModule = None
  74. def _invokeantlr(self, dir, file, options):
  75. fp = os.popen('cd %s; java %s org.antlr.Tool %s %s 2>&1'
  76. % (dir, classpath, options, file)
  77. )
  78. output = ''
  79. failed = False
  80. for line in fp:
  81. output += line
  82. if line.startswith('error('):
  83. failed = True
  84. rc = fp.close()
  85. if rc is not None:
  86. failed = True
  87. if failed:
  88. raise RuntimeError(
  89. "Failed to compile grammar '%s':\n\n" % file
  90. + output
  91. )
  92. def compileGrammar(self, grammarName=None, options=''):
  93. if grammarName is None:
  94. grammarName = self.baseName + '.g'
  95. # don't try to rebuild grammar, if it already failed
  96. if grammarName in compileErrorCache:
  97. return
  98. try:
  99. testDir = os.path.dirname(os.path.abspath(__file__))
  100. # get dependencies from antlr
  101. if grammarName in dependencyCache:
  102. dependencies = dependencyCache[grammarName]
  103. else:
  104. dependencies = []
  105. cmd = ('cd %s; java %s org.antlr.Tool -depend %s 2>&1'
  106. % (testDir, classpath, grammarName)
  107. )
  108. output = ""
  109. failed = False
  110. fp = os.popen(cmd)
  111. for line in fp:
  112. output += line
  113. if line.startswith('error('):
  114. failed = True
  115. elif ':' in line:
  116. a, b = line.strip().split(':', 1)
  117. dependencies.append(
  118. (os.path.join(testDir, a.strip()),
  119. [os.path.join(testDir, b.strip())])
  120. )
  121. rc = fp.close()
  122. if rc is not None:
  123. failed = True
  124. if failed:
  125. raise RuntimeError(
  126. "antlr -depend failed with code %s on grammar '%s':\n\n"
  127. % (rc, grammarName)
  128. + cmd
  129. + "\n"
  130. + output
  131. )
  132. # add dependencies to my .stg files
  133. templateDir = os.path.abspath(os.path.join(testDir, '..', '..', '..', 'src', 'org', 'antlr', 'codegen', 'templates', 'Python'))
  134. templates = glob.glob(os.path.join(templateDir, '*.stg'))
  135. for dst, src in dependencies:
  136. src.extend(templates)
  137. dependencyCache[grammarName] = dependencies
  138. rebuild = False
  139. for dest, sources in dependencies:
  140. if not os.path.isfile(dest):
  141. rebuild = True
  142. break
  143. for source in sources:
  144. if os.path.getmtime(source) > os.path.getmtime(dest):
  145. rebuild = True
  146. break
  147. if rebuild:
  148. self._invokeantlr(testDir, grammarName, options)
  149. except:
  150. # mark grammar as broken
  151. compileErrorCache[grammarName] = True
  152. raise
  153. def lexerClass(self, base):
  154. """Optionally build a subclass of generated lexer class"""
  155. return base
  156. def parserClass(self, base):
  157. """Optionally build a subclass of generated parser class"""
  158. return base
  159. def walkerClass(self, base):
  160. """Optionally build a subclass of generated walker class"""
  161. return base
  162. def __load_module(self, name):
  163. modFile, modPathname, modDescription \
  164. = imp.find_module(name, [os.path.dirname(__file__)])
  165. return imp.load_module(
  166. name, modFile, modPathname, modDescription
  167. )
  168. def getLexer(self, *args, **kwargs):
  169. """Build lexer instance. Arguments are passed to lexer.__init__()."""
  170. self.lexerModule = self.__load_module(self.baseName + 'Lexer')
  171. cls = getattr(self.lexerModule, self.baseName + 'Lexer')
  172. cls = self.lexerClass(cls)
  173. lexer = cls(*args, **kwargs)
  174. return lexer
  175. def getParser(self, *args, **kwargs):
  176. """Build parser instance. Arguments are passed to parser.__init__()."""
  177. self.parserModule = self.__load_module(self.baseName + 'Parser')
  178. cls = getattr(self.parserModule, self.baseName + 'Parser')
  179. cls = self.parserClass(cls)
  180. parser = cls(*args, **kwargs)
  181. return parser
  182. def getWalker(self, *args, **kwargs):
  183. """Build walker instance. Arguments are passed to walker.__init__()."""
  184. self.walkerModule = self.__load_module(self.baseName + 'Walker')
  185. cls = getattr(self.walkerModule, self.baseName + 'Walker')
  186. cls = self.walkerClass(cls)
  187. walker = cls(*args, **kwargs)
  188. return walker
  189. def compileInlineGrammar(self, grammar, options=''):
  190. testDir = os.path.dirname(os.path.abspath(__file__))
  191. # get type and name from first grammar line
  192. m = re.match(r'\s*((lexer|parser|tree)\s+|)grammar\s+(\S+);', grammar)
  193. assert m is not None
  194. grammarType = m.group(2)
  195. if grammarType is None:
  196. grammarType = 'combined'
  197. grammarName = m.group(3)
  198. assert grammarType in ('lexer', 'parser', 'tree', 'combined'), grammarType
  199. # dump temp grammar file
  200. fp = open(os.path.join(testDir, grammarName + '.g'), 'w')
  201. fp.write(grammar)
  202. fp.close()
  203. # compile it
  204. self._invokeantlr(testDir, grammarName + '.g', options)
  205. if grammarType == 'combined':
  206. lexerMod = self.__load_module(grammarName + 'Lexer')
  207. lexerCls = getattr(lexerMod, grammarName + 'Lexer')
  208. lexerCls = self.lexerClass(lexerCls)
  209. parserMod = self.__load_module(grammarName + 'Parser')
  210. parserCls = getattr(parserMod, grammarName + 'Parser')
  211. parserCls = self.parserClass(parserCls)
  212. return lexerCls, parserCls
  213. if grammarType == 'lexer':
  214. lexerMod = self.__load_module(grammarName + 'Lexer')
  215. lexerCls = getattr(lexerMod, grammarName + 'Lexer')
  216. lexerCls = self.lexerClass(lexerCls)
  217. return lexerCls
  218. if grammarType == 'parser':
  219. parserMod = self.__load_module(grammarName + 'Parser')
  220. parserCls = getattr(parserMod, grammarName + 'Parser')
  221. parserCls = self.parserClass(parserCls)
  222. return parserCls
  223. if grammarType == 'tree':
  224. walkerMod = self.__load_module(grammarName)
  225. walkerCls = getattr(walkerMod, grammarName)
  226. walkerCls = self.walkerClass(walkerCls)
  227. return walkerCls