Newer
Older
zweic / unittest.py
@glproj03 glproj03 on 27 Jan 2006 3 KB unittest v1
#usage: python check.py --help
COMPILER = "scala -cp classes zweic.GeneratorTest"
RISC = "java -cp risc/lib/risc.jar risc.emulator.Main"
OUTDIR = "asm"

import sys, os, re
from optparse import OptionParser

rx_isut = re.compile(r'//[^#]*#' \
					 'is(?:ut|unittest)', re.I)

rx_tl = re.compile(r'//[^#]*#' \
				   r'(?!is(?:ut|unittest))' \
				   r'(.*)', re.I)

class Checker:
	def __init__(self, spath, options):
		self.isUT = False
		
		self.fname = os.path.splitext(os.path.basename(spath))[0]
		self.spath = spath
		self.options = options
		
		self.compile()

		solution = self.parseUnitTest(self.spath)
		
		if self.isUT:			
			self.check(solution)

		print
		
	def compile(self):
		print '> compiling %s' % self.fname,

		# call compiler via internal shell and redirect output to file
		pipes = os.popen3(r'%s %s > %s' %
						  (self.options.compiler, self.spath,
						   os.path.join(self.options.outdir, self.fname+'.asm')))

		errs = pipes[2].read()
		print '.'
		if errs:
			print >>sys.stderr, errs
			sys.exit(1)		


	def check(self, solution):
		# call risc emu via internal shell and pipe output
		pipes = os.popen3(r'%s asm/%s.asm' % (self.options.risc, self.fname))
		errs = pipes[2].read()
		if errs:
			print >>sys.stderr, errs
			sys.exit(2)
		answer = pipes[1].read()	

		if solution == answer:
			print "> checked: ok" 
		else:
			self.error(solution, answer)

		
	def parseUnitTest(self, path):
		ret = []
		for line in open(path):
			if rx_isut.search(line):
				#this is a file containing meta information
				self.isUT = True

			match = rx_tl.search(line)
			if self.isUT and match:
				#replace newlines
				f = match.group(1).replace(r'\n','\n')			
				ret.append(f)
				
		return "".join(ret)

		
	def error(self, expected, found):
		# error message for broken files
		expected = expected.split('\n')
		found = found.split('\n')
		
		print >>sys.stderr, "* '%s' broken: " % self.fname			
		print >>sys.stderr, "%-50s %s" % ("expected", "found")
		for e, f in xzip(expected, found):
			print >>sys.stderr, "%-50s %s" % (e, f)


def xzip(l1, l2):
	for x in range(max(len(l1), len(l2))):
		e = ''
		f = ''			
		if len(l1) > x:
			e = l1[x]
		if len(l2) > x:
			f = l2[x]			
		yield e, f

		
if __name__ == '__main__':
	optpar = OptionParser()
	optpar.add_option(
		"-c", "--compiler", dest="compiler",					  
		help="Command to execute the compiler, default: '%s'" % COMPILER,
		default=COMPILER, metavar="COMPILER")

	optpar.add_option(
		"-a", "--risc", dest="risc",					  
		help="Command to execute the risc emulator, default: '%s'" % RISC,
		default=RISC, metavar="RISC")

	optpar.add_option(
		"-o", "--outdir", dest="outdir",					  
		help="Path where to store compiled sources, default: '%s'" % OUTDIR,
		default=OUTDIR, metavar="OUTDIR")

	(options, args) = optpar.parse_args()

	try:
		os.makedirs(options.outdir)
	except Exception, (errno, strerror):
		if not errno == 17:
			print >>sys.stderr, strerror
	for source in args:
		Checker(source, options)