Skip to content

Instantly share code, notes, and snippets.

@sma
Created August 3, 2009 18:08
Show Gist options
  • Save sma/160726 to your computer and use it in GitHub Desktop.
Save sma/160726 to your computer and use it in GitHub Desktop.
pyspec compiler
#!/usr/bin/env python
import re
def pyspec(source):
def translate(lines):
def name(n):
return re.sub("_+", "_", re.sub(r"[\s\W]+", "_", n)).strip("_")
def on_describe(m):
r"""(\s*)describe\s+("[^"]*"|'[^']*'|[^:]+?)\s*:"""
return "class %sTest(unittest.TestCase):" % name(m.group(2))
def on_before(m):
r"""(\s*)before\s*:"""
return "def setUp(self):"
def on_after(m):
r"""(\s*)after\s*:"""
return "def tearDown(self):"
def on_it(m):
r"""(\s*)it\s+("[^"]*"|'[^']*'|[^:]+?)\s*:"""
return "def test_that_it_%s(self):" % name(m.group(2))
def on_should(m):
r"""(\s*)(.*?)\s+should\s+(==|!=|<=?|>=?|is(?:\s+not)?|(?:not\s+)in)\s+(.*)"""
return 'assert %s %s %s, "%s should be %s %%r but was %%r" %% (%s, %s)' % (
m.group(2), m.group(3), m.group(4),
m.group(2).replace('"', '\\"'), m.group(3), m.group(4), m.group(2))
def on_pending(m):
r"""(\s*)pending$"""
return 'assert False, "not yet implemented"'
patterns = []
for n, v in locals().items():
if n.startswith("on_"):
patterns.append([re.compile(v.__doc__), v])
yield "import unittest"
for line in lines:
for p, f in patterns:
m = p.match(line)
if m:
yield "%s%s%s" % (m.group(1), f(m), line[m.end():])
break
else:
yield line
import sys
exec "\n".join(translate(source.splitlines())) in sys._getframe(1).f_globals
def main():
import sys, unittest
for name in sys.argv[1:]:
f = open(name)
try:
pyspec(f.read())
finally:
f.close()
unittest.main(argv=sys.argv[:1])
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment