1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2008 The University of Melbourne
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
# Author: Dilshan Angampitiya
23
This file provides the function parse_tutorial_file which takes an
24
xml specification of a tutorial problem file and returns a test suite object
25
for that problem. It throws a ParseException if there was a problem parsing
29
from xml.dom.minidom import *
30
from TestFramework import *
32
DEFAULT_TEST_TYPE = 'norm'
33
DEFAULT_CASE_TYPE = 'match'
35
class ParseException(Exception):
36
" Error when parsing the xml problem file "
37
def __init___(self, reason):
43
def getTextData(element):
44
""" Get the text and cdata inside an element
45
Leading and trailing whitespace are stripped
48
for child in element.childNodes:
49
if child.nodeType == child.CDATA_SECTION_NODE:
51
if child.nodeType == child.TEXT_NODE:
56
def getCasePartData(partNode):
57
""" Create an TestCasePaart instance from test part xml data
60
func_desc = partNode.getAttribute('desc')
61
default = partNode.getAttribute('default')
62
if default == '': default = DEFAULT_CASE_TYPE
64
part = TestCasePart(func_desc, default)
66
for child in partNode.childNodes:
67
if child.nodeType != child.ELEMENT_NODE:
70
if child.tagName == 'stdout':
71
test_type = child.getAttribute('type')
72
if test_type == '': test_type = DEFAULT_TEST_TYPE
73
part.add_stdout_test(getTextData(child), test_type)
74
elif child.tagName == 'stderr':
75
test_type = child.getAttribute('type')
76
if test_type == '': test_type = DEFAULT_TEST_TYPE
77
part.add_stderr_test(getTextData(child), test_type)
78
elif child.tagName == 'file':
79
test_type = child.getAttribute('type')
80
if test_type == '': test_type = DEFAULT_TEST_TYPE
81
filename = child.getAttribute('name')
83
raise ParseException("File without name in case %s" %case_name)
84
part.add_file_test(filename, getTextData(child), test_type)
88
def getCaseData(caseNode):
89
""" Creare a TestCase instance from test case xml data
92
case_name = caseNode.getAttribute('name')
93
function = caseNode.getAttribute('function')
94
if function == '': function = None
95
case = TestCase(case_name, function)
97
for child in caseNode.childNodes:
98
if child.nodeType != child.ELEMENT_NODE:
101
if child.tagName == 'stdin':
103
case.set_stdin(getTextData(child))
104
elif child.tagName == 'file':
106
filename = child.getAttribute('name')
108
raise ParseException("File without name in case %s" %case_name)
109
case.add_file(filename, getTextData(child))
110
elif child.tagName == 'var':
112
var_name = child.getAttribute('name')
113
var_val = child.getAttribute('value')
114
if not var_name or not var_val:
115
raise ParseException("Incomplete variable in case %s" %case_name)
116
case.add_variable(var_name, var_val)
117
elif child.tagName == 'arg':
119
arg_val = child.getAttribute('value')
120
arg_name = child.getAttribute('name')
121
if arg_name == '': arg_name = None
124
raise ParseException("Incomplete argument in case %s" %case_name)
125
case.add_arg(arg_val, arg_name)
126
elif child.tagName == 'function':
127
# specify a test case part
128
case.add_part(getCasePartData(child))
132
def parse_tutorial_file(filename, prob_num=1):
133
""" Parse an xml problem file and return a testsuite for that problem """
134
dom = parse(filename)
139
for child in dom.childNodes:
140
if child.nodeType == child.ELEMENT_NODE and child.tagName == 'problem':
142
if count == prob_num:
147
raise ParseException("Not enough problems")
150
problem_name = problem.getAttribute('name')
153
raise ParseException('Problem name not supplied')
155
problem_suite = TestSuite(problem_name)
157
# get solution and include info
158
for child in problem.childNodes:
159
if child.nodeType != child.ELEMENT_NODE:
161
if child.tagName == 'solution':
162
problem_suite.add_solution(getTextData(child))
163
elif child.tagName == 'include':
164
problem_suite.add_include_code(getTextData(child))
165
elif child.tagName == 'case':
166
problem_suite.add_case(getCaseData(child))