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 TestCasePart instance from test part xml data
60
func_desc = partNode.getAttribute('desc')
61
func_pass = partNode.getAttribute('pass')
62
func_fail = partNode.getAttribute('fail')
67
default = partNode.getAttribute('default')
68
if default == '': default = DEFAULT_CASE_TYPE
70
part = TestCasePart(func_pass, func_fail, default)
72
for child in partNode.childNodes:
73
if child.nodeType != child.ELEMENT_NODE:
76
if child.tagName == 'stdout':
77
test_type = child.getAttribute('type')
78
if test_type == '': test_type = DEFAULT_TEST_TYPE
79
part.add_stdout_test(getTextData(child), test_type)
80
elif child.tagName == 'stderr':
81
test_type = child.getAttribute('type')
82
if test_type == '': test_type = DEFAULT_TEST_TYPE
83
part.add_stderr_test(getTextData(child), test_type)
84
elif child.tagName == 'exception':
85
test_type = child.getAttribute('type')
86
if test_type == '': test_type = DEFAULT_TEST_TYPE
87
part.add_exception_test(getTextData(child), test_type)
88
elif child.tagName == 'file':
89
test_type = child.getAttribute('type')
90
if test_type == '': test_type = DEFAULT_TEST_TYPE
91
filename = child.getAttribute('name')
93
raise ParseException("File without name in case %s" %case_name)
94
part.add_file_test(filename, getTextData(child), test_type)
95
elif child.tagName == 'code':
96
test_type = child.getAttribute('type')
97
if test_type == '': test_type = DEFAULT_TEST_TYPE
98
part.add_code_test(getTextData(child), test_type)
102
def getCaseData(caseNode):
103
""" Creare a TestCase instance from test case xml data
106
case_name = caseNode.getAttribute('name')
107
function = caseNode.getAttribute('function')
108
if function == '': function = None
109
case = TestCase(case_name, function)
111
for child in caseNode.childNodes:
112
if child.nodeType != child.ELEMENT_NODE:
115
if child.tagName == 'stdin':
117
case.set_stdin(getTextData(child))
118
elif child.tagName == 'file':
120
filename = child.getAttribute('name')
122
raise ParseException("File without name in case %s" %case_name)
123
case.add_file(filename, getTextData(child))
124
elif child.tagName == 'var':
126
var_name = child.getAttribute('name')
127
var_val = child.getAttribute('value')
128
if not var_name or not var_val:
129
raise ParseException("Incomplete variable in case %s" %case_name)
130
case.add_variable(var_name, var_val)
131
elif child.tagName == 'arg':
133
arg_val = child.getAttribute('value')
134
arg_name = child.getAttribute('name')
135
if arg_name == '': arg_name = None
138
raise ParseException("Incomplete argument in case %s" %case_name)
139
case.add_arg(arg_val, arg_name)
140
elif child.tagName == 'exception':
141
exception_name = child.getAttribute('name')
142
if not exception_name:
143
raise ParseException("Incomplete exception in case %s" %case_name)
144
case.add_exception(exception_name)
145
elif child.tagName == 'function':
146
# specify a test case part
147
case.add_part(getCasePartData(child))
151
def parse_tutorial_file(filename, prob_num=1):
152
""" Parse an xml problem file and return a testsuite for that problem """
153
dom = parse(filename)
158
for child in dom.childNodes:
159
if child.nodeType == child.ELEMENT_NODE and child.tagName == 'problem':
161
if count == prob_num:
166
raise ParseException("Not enough problems")
169
problem_name = problem.getAttribute('name')
172
raise ParseException('Problem name not supplied')
174
problem_suite = TestSuite(problem_name)
176
# get solution and include info
177
for child in problem.childNodes:
178
if child.nodeType != child.ELEMENT_NODE:
180
if child.tagName == 'solution':
181
problem_suite.add_solution(getTextData(child))
182
elif child.tagName == 'include':
183
problem_suite.add_include_code(getTextData(child))
184
elif child.tagName == 'case':
185
problem_suite.add_case(getCaseData(child))