-
Jan Maximilian Michal authored
* Set the STOP_ON_PASS setting in the grady/settings/instance.py * Currently uses signals and does not check if the feedback is final or not. * Feedback is validated until the end * Minor fixes in the importer
Jan Maximilian Michal authored* Set the STOP_ON_PASS setting in the grady/settings/instance.py * Currently uses signals and does not check if the feedback is final or not. * Feedback is validated until the end * Minor fixes in the importer
testcases.py 2.51 KiB
import os
import random
import re
from string import ascii_letters, digits
try:
import processing
except ModuleNotFoundError:
from util import processing
types = ('integer', 'unsigned_integer', 'character', 'string')
list_sep = '...'
re_task = re.compile(r'^-- (?P<title>.*)\n(USAGE: (?P<cmd>[\./\w]+) (?P<syntax>.*)|NO EXECUTABLE)', re.MULTILINE) # noqa: E501
re_args = re.compile(rf"<({'|'.join(types)}|{'|'.join(t + '_list' for t in types)})>") # noqa: E501
def call_function(name: str, *args, **kwargs):
return globals()[name](*args, **kwargs)
def integer(bounds=50):
return random.randint(-bounds, bounds)
def unsigned_integer(upper=50):
return random.randint(0, upper)
def character():
return random.choice(10 * ascii_letters + 2 * digits + '%*+,-./:?@[]^_{}~')
def string(lenght=31):
return ''.join(character() for i in range(2, 2 + unsigned_integer(lenght)))
def type_list(_type):
def generic_list():
return ' '.join(str(
call_function(_type)) for i in range(2, unsigned_integer(6) * 2))
return generic_list
def rubbish():
return str(call_function(
random.choice(tuple(t + '_list' for t in types) + types)))
def argument_generator(syntax):
syntax, _ = re.subn(
r'<([\w\s]+)> <\1> \.\.\. <\1> <\1>', r'<\1_list>', syntax)
syntax, _ = re.subn(r'<(\w+)\s(\w+)>', r'<\1_\2>', syntax)
return ' '.join(
str(call_function(arg)) for arg in re.findall(re_args, syntax))
def testcases_generator(task, n=10):
syntax = task.group('syntax')
if not syntax:
return
if syntax == 'NO INPUT':
yield 'NO INPUT'
return
for i in range(n):
yield argument_generator(syntax)
def testcases(description_path):
for t in types:
globals()[t + '_list'] = type_list(t) # I fucking love it
with open(description_path) as description_file:
description = description_file.read()
return {
task['title']: {
'cmd': task['cmd'],
'cases': [t for t in testcases_generator(task)]
} for task in re.finditer(re_task, description)
}
def evaluated_testcases(description_path, binaries):
task_testcases = testcases(description_path)
for task in filter(lambda t: t['cmd'], task_testcases.values()):
path_to_binary = os.path.join(os.path.join(
binaries, os.path.basename(task['cmd'])))
task['results'] = [processing.run_cmd(
f"{path_to_binary} {case}").stdout for case in task['cases']]
return task_testcases