diff 2.00/test-svn.py @ 21:ec6f1a132109

A pretty usable version Test groups and testconfs in non-ZIP archives or ZIP archives with comments are not yet supported.
author Oleg Oshmyan <chortos@inbox.lv>
date Fri, 06 Aug 2010 15:39:29 +0000
parents a33653cdad57
children f07b7a431ea6
line wrap: on
line diff
--- a/2.00/test-svn.py	Mon Jun 14 21:02:06 2010 +0000
+++ b/2.00/test-svn.py	Fri Aug 06 15:39:29 2010 +0000
@@ -1,9 +1,14 @@
-#!/usr/bin/python
+#! /usr/bin/env python
 # Copyright (c) 2009-2010 Chortos-2 <chortos@inbox.lv>
 
 from __future__ import division, with_statement
 import optparse, sys, compat
-from compat import say
+
+def import_error(e):
+	say('Error: your installation of test.py is incomplete;', str(e).lower() + '.', file=sys.stderr)
+	sys.exit(3)
+
+from compat import *
 
 # $Rev$
 version = '2.00.0 (SVN r$$REV$$)'
@@ -11,6 +16,9 @@
 parser.add_option('-u', '--update', dest='update', action='store_true', default=False, help='check for an updated version of test.py')
 parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='create a copy of the input/output files of the last test case for manual testing and exit')
 parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed after finishing testing')
+parser.add_option('-s', '--save-io', dest='erase', action='store_false', default=True, help='do not delete the copies of input/output files after the last test case; create copies of input files and store output in files even if the solution uses standard I/O; delete the stored input/output files if the solution uses standard I/O and the -c/--cleanup option is specified')
+parser.add_option('-t', '--detect-time', dest='autotime', action='store_true', default=False, help='spend a second detecting the most precise time measurement function')
+parser.add_option('--no-time-limits', dest='no_maxtime', action='store_true', default=False, help='disable all time limits')
 
 options, args = parser.parse_args()
 parser.destroy()
@@ -49,73 +57,115 @@
 	say('Downloaded and installed. Now you are using test.py ' + latesttext + '.')
 	sys.exit()
 
-def import_error(e):
-	say('Your installation of test.py is incomplete:', str(e).lower() + '.', file=sys.stderr)
-	sys.exit(3)
-
-import os, config
+import config, itertools, os, sys, time
 
-# Do this check here so that if we have to warn them, we do it as early as possible
-if options.pause and not hasattr(config, 'pause'):
-	try:
-		# If we have getch, we don't need config.pause
-		import msvcrt
-		msvcrt.getch.__call__
-	except Exception:
-		if os.name == 'posix':
-			config.pause = 'read -s -n 1'
-			say('Warning: configuration variable pause is not defined; it was devised automatically but the choice might be incorrect, so test.py might exit immediately after the testing is completed.')
-			sys.stdout.flush()
-		elif os.name == 'nt':
-			config.pause = 'pause'
-		else:
-			sys.exit('Error: configuration variable pause is not defined and cannot be devised automatically.')
+if options.autotime:
+	c = time.clock()
+	time.sleep(1)
+	c = time.clock() - c
+	if int(c + .5) == 1:
+		clock = time.clock
+	else:
+		clock = time.time
+elif sys.platform == 'win32':
+	clock = time.clock
+else:
+	clock = time.time
 
 try:
-	from problem import *
-except ImportError as e:
-	import_error(e)
+	globalconf = config.load_global()
 
-# Support single-problem configurations
-try:
-	shouldprintnames = len(config.tasknames) > 1
-except Exception:
-	shouldprintnames = True
+	# Do this check here so that if we have to warn them, we do it as early as possible
+	if options.pause and not hasattr(globalconf, 'pause'):
+		try:
+			# If we have getch, we don't need config.pause
+			import msvcrt
+			msvcrt.getch.__call__
+		except Exception:
+			if os.name == 'posix':
+				globalconf.pause = 'read -s -n 1'
+				say('Warning: configuration variable pause is not defined; it was devised automatically but the choice might be incorrect, so test.py might exit immediately after the testing is completed.')
+				sys.stdout.flush()
+			elif os.name == 'nt':
+				globalconf.pause = 'pause'
+			else:
+				sys.exit('Error: configuration variable pause is not defined and cannot be devised automatically.')
 
-ntasks = 0
-nfulltasks = 0
-maxscore = 0
-realscore = 0
+	try:
+		from problem import *
+	except ImportError:
+		import_error(sys.exc_info()[1])
 
-for taskname in config.tasknames:
-	problem = Problem(taskname)
-	
-	if ntasks: say()
-	if shouldprintnames: say(taskname)
-	
-	if options.copyonly:
-		problem.copytestdata()
+	# Support single-problem configurations
+	if globalconf.tasknames is None:
+		shouldprintnames = False
+		globalconf.multiproblem = False
+		globalconf.tasknames = os.path.curdir,
 	else:
-		real, max = problem.test()
-	
-	ntasks += 1
-	nfulltasks += (real == max)
-	realscore += real
-	maxscore += max
+		globalconf.multiproblem = True
+		try:
+			shouldprintnames = len(globalconf.tasknames) > 1
+		except Exception:
+			# Try to retrieve the first two problem names and cache them on success
+			globalconf.tasknames = iter(globalconf.tasknames)
+			try:
+				try:
+					first = next(globalconf.tasknames)
+				except NameError:
+					# Python 2.5 lacks the next() built-in
+					first = globalconf.tasknames.next()
+			except StopIteration:
+				globalconf.tasknames = ()
+				shouldprintnames = False
+			else:
+				try:
+					try:
+						second = next(globalconf.tasknames)
+					except NameError:
+						second = globalconf.tasknames.next()
+				except StopIteration:
+					globalconf.tasknames = first,
+					shouldprintnames = False
+				else:
+					globalconf.tasknames = itertools.chain((first, second), globalconf.tasknames)
+					shouldprintnames = True
 
-if options.copyonly:
-	sys.exit()
+	ntasks = 0
+	nfulltasks = 0
+	maxscore = 0
+	realscore = 0
 
-if ntasks != 1:
-	say()
-	say('Grand grand total: %g/%g weighted points; %d/%d problems solved fully' % (realscore, maxscore, nfulltasks, ntasks))
+	for taskname in globalconf.tasknames:
+		problem = Problem(taskname)
+		
+		if ntasks: say()
+		if shouldprintnames: say(taskname)
+		
+		if options.copyonly:
+			problem.copytestdata()
+		else:
+			real, max = problem.test()
+		
+		ntasks += 1
+		nfulltasks += (real == max)
+		realscore += real
+		maxscore += max
+
+	if options.copyonly:
+		sys.exit()
+
+	if ntasks != 1:
+		say()
+		say('Grand grand total: %g/%g weighted points; %d/%d problems solved fully' % (realscore, maxscore, nfulltasks, ntasks))
+except KeyboardInterrupt:
+	sys.exit('Exiting due to a keyboard interrupt.')
 
 if options.pause:
-	say('Press any key to exit...', end='')
+	say('Press any key to exit...')
 	sys.stdout.flush()
 	
 	try:
 		import msvcrt
 		msvcrt.getch()
 	except Exception:
-		os.system(config.pause + ' >' + os.devnull)
\ No newline at end of file
+		os.system(globalconf.pause + ' >' + os.devnull)
\ No newline at end of file