comparison 2.00/testcases.py @ 23:c1f52b5d80d6

Compatibility and bug fixes -1 command line option added (currently only detects the presence of test groups). The ansname configuration variable is now (again) optional when output validators are used. Bug fix: path realization only looked at paths beginning with tests/. Bug fix: non-reiterable values of the tests configuration variable are now handled correctly. Bug fix: an exceptions was raised if a problem had no test cases.
author Oleg Oshmyan <chortos@inbox.lv>
date Wed, 22 Sep 2010 23:34:51 +0000
parents f07b7a431ea6
children c23d81f4a1a3
comparison
equal deleted inserted replaced
22:f07b7a431ea6 23:c1f52b5d80d6
325 elif callable(case.validator): 325 elif callable(case.validator):
326 return case.validator(output) 326 return case.validator(output)
327 else: 327 else:
328 # Call the validator program 328 # Call the validator program
329 output.close() 329 output.close()
330 case.open_outfile() 330 if case.problem.config.ansname:
331 case.outfile.copy(case.problem.config.ansname) 331 case.open_outfile()
332 case.outfile.copy(case.problem.config.ansname)
332 case.process = Popen(case.validator, stdin=devnull, stdout=PIPE, stderr=STDOUT, universal_newlines=True, bufsize=-1) 333 case.process = Popen(case.validator, stdin=devnull, stdout=PIPE, stderr=STDOUT, universal_newlines=True, bufsize=-1)
333 comment = case.process.communicate()[0].strip() 334 comment = case.process.communicate()[0].strip()
334 lower = comment.lower() 335 lower = comment.lower()
335 match = re.match(r'(ok|correct|wrong(?:(?:\s|_)*answer)?)(?:$|\s+|[.,!:]+\s*)', lower) 336 match = re.match(r'(ok|correct|wrong(?:(?:\s|_)*answer)?)(?:$|\s+|[.,!:]+\s*)', lower)
336 if match: 337 if match:
379 inputdatafname = case.problem.config.inname 380 inputdatafname = case.problem.config.inname
380 context = Copying(case.infile, inputdatafname) 381 context = Copying(case.infile, inputdatafname)
381 with context: 382 with context:
382 with open(inputdatafname, 'rU') as infile: 383 with open(inputdatafname, 'rU') as infile:
383 with tempfile.TemporaryFile('w+') if options.erase and not case.validator else open(case.problem.config.outname, 'w+') as outfile: 384 with tempfile.TemporaryFile('w+') if options.erase and not case.validator else open(case.problem.config.outname, 'w+') as outfile:
385 # TODO: make sure outfile.file is passed to Popen if needed
384 try: 386 try:
385 try: 387 try:
386 case.process = Popen(case.problem.config.path, stdin=infile, stdout=outfile, stderr=devnull, universal_newlines=True, bufsize=-1, preexec_fn=preexec_fn) 388 case.process = Popen(case.problem.config.path, stdin=infile, stdout=outfile, stderr=devnull, universal_newlines=True, bufsize=-1, preexec_fn=preexec_fn)
387 except MemoryError: 389 except MemoryError:
388 # If there is not enough memory for the forked test.py, 390 # If there is not enough memory for the forked test.py,
474 476
475 def load_problem(prob, _types={'batch' : BatchTestCase, 477 def load_problem(prob, _types={'batch' : BatchTestCase,
476 'outonly' : OutputOnlyTestCase, 478 'outonly' : OutputOnlyTestCase,
477 'bestout' : BestOutputTestCase, 479 'bestout' : BestOutputTestCase,
478 'reactive': ReactiveTestCase}): 480 'reactive': ReactiveTestCase}):
481 if options.legacy:
482 prob.config.usegroups = False
483 prob.config.tests = list(prob.config.tests)
484 for i, name in enumerate(prob.config.tests):
485 try:
486 if len(name) > 1:
487 prob.config.usegroups = True
488 break
489 elif len(name):
490 prob.config.tests[i] = name[0]
491 except Exception:
492 try:
493 # Try to retrieve the first two test case ID's and cache them on success
494 prob.config.tests[i] = name = iter(name)
495 except TypeError:
496 continue
497 try:
498 try:
499 first = next(name)
500 except NameError:
501 # Python 2.5 lacks the next() built-in
502 first = name.next()
503 except StopIteration:
504 prob.config.tests[i] = ()
505 else:
506 try:
507 try:
508 second = next(name)
509 except NameError:
510 second = name.next()
511 except StopIteration:
512 prob.config.tests[i] = first
513 else:
514 prob.config.tests[i] = itertools.chain((first, second), name)
515 prob.config.usegroups = True
516 break
479 if prob.config.usegroups: 517 if prob.config.usegroups:
480 # FIXME: test groups should again be supported! 518 # FIXME: test groups should again be supported!
481 pass 519 pass
482 else: 520 else:
483 # We will need to iterate over these configuration variables twice 521 # We will need to iterate over these configuration variables twice
486 except Exception: 524 except Exception:
487 prob.config.dummies = tuple(prob.config.dummies) 525 prob.config.dummies = tuple(prob.config.dummies)
488 try: 526 try:
489 len(prob.config.tests) 527 len(prob.config.tests)
490 except Exception: 528 except Exception:
491 prob.config.dummies = tuple(prob.config.tests) 529 prob.config.tests = tuple(prob.config.tests)
492 # First get prob.cache.padoutput right 530 # First get prob.cache.padoutput right
493 for i in prob.config.dummies: 531 for i in prob.config.dummies:
494 s = 'sample ' + str(i).zfill(prob.config.paddummies) 532 s = 'sample ' + str(i).zfill(prob.config.paddummies)
495 prob.cache.padoutput = max(prob.cache.padoutput, len(s)) 533 prob.cache.padoutput = max(prob.cache.padoutput, len(s))
496 for i in prob.config.tests: 534 for i in prob.config.tests: