~azzar1/unity/add-show-desktop-key

512 by stevenbird
Renaming of problems to exercises (initial commit).
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2008 The University of Melbourne
3
#
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.
8
#
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.
13
#
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
17
513 by stevenbird
test/test_framework/*, exercises/sample/*
18
# Module: parse_exercise
512 by stevenbird
Renaming of problems to exercises (initial commit).
19
# Author: Dilshan Angampitiya
513 by stevenbird
test/test_framework/*, exercises/sample/*
20
#         Steven Bird (revisions)
512 by stevenbird
Renaming of problems to exercises (initial commit).
21
# Date:   24/1/2008
22
23
"""
513 by stevenbird
test/test_framework/*, exercises/sample/*
24
This file provides the function parse_exercise_file which takes an xml
25
specification of an exercise file and returns a test suite object for
26
that exercise. It throws a ParseException if there was a problem
27
parsing the file.
512 by stevenbird
Renaming of problems to exercises (initial commit).
28
"""
29
30
from xml.dom.minidom import *
31
from TestFramework import *
32
33
DEFAULT_TEST_TYPE = 'norm'
34
DEFAULT_CASE_TYPE = 'match'
35
36
class ParseException(Exception):
513 by stevenbird
test/test_framework/*, exercises/sample/*
37
    " Error when parsing the xml exercise file "
512 by stevenbird
Renaming of problems to exercises (initial commit).
38
    def __init___(self, reason):
39
        self._reason = reason
40
41
    def __str__(self):
42
        return self._reason
43
44
def getTextData(element):
45
    """ Get the text and cdata inside an element
46
    Leading and trailing whitespace are stripped
47
    """
48
    data = ''
49
    for child in element.childNodes:
50
        if child.nodeType == child.CDATA_SECTION_NODE:
51
            data += child.data
52
        if child.nodeType == child.TEXT_NODE:
53
            data += child.data
54
55
    return data.strip()
56
57
def getCasePartData(partNode):
58
    """ Create an TestCasePart instance from test part xml data
59
    """
60
    
61
    func_pass = partNode.getAttribute('pass')
62
    func_fail = partNode.getAttribute('fail')
63
    default = partNode.getAttribute('default')
64
    if default == '': default = DEFAULT_CASE_TYPE
65
    
66
    part = TestCasePart(func_pass, func_fail, default)
67
68
    for child in partNode.childNodes:
69
        if child.nodeType != child.ELEMENT_NODE:
70
            continue
71
72
        if child.tagName == 'stdout':
73
            test_type = child.getAttribute('type')
74
            if test_type == '': test_type = DEFAULT_TEST_TYPE
75
            part.add_stdout_test(getTextData(child), test_type)
76
        elif child.tagName == 'stderr':
77
            test_type = child.getAttribute('type')
78
            if test_type == '': test_type = DEFAULT_TEST_TYPE
79
            part.add_stderr_test(getTextData(child), test_type)
716 by mattgiuca
Test Framework: Numerous bug fixes.
80
        elif child.tagName == 'result':
81
            test_type = child.getAttribute('type')
82
            if test_type == '': test_type = DEFAULT_TEST_TYPE
83
            part.add_result_test(getTextData(child), test_type)
512 by stevenbird
Renaming of problems to exercises (initial commit).
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')
92
            if filename == '':
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)
99
100
    return part
101
1029 by dcoles
Tutorial Service: Ported the tutorial service to the console so that all
102
def getCaseData(caseNode, console):
523 by stevenbird
Adding ReStructured Text preprocessing of exercise descriptions,
103
    """ Create a TestCase instance from test case xml data
512 by stevenbird
Renaming of problems to exercises (initial commit).
104
    """
105
    
106
    case_name = caseNode.getAttribute('name')
107
    function = caseNode.getAttribute('function')
108
    if function == '': function = None
1029 by dcoles
Tutorial Service: Ported the tutorial service to the console so that all
109
    case = TestCase(console, case_name, function)
512 by stevenbird
Renaming of problems to exercises (initial commit).
110
    
111
    for child in caseNode.childNodes:
112
        if child.nodeType != child.ELEMENT_NODE:
113
            continue
114
115
        if child.tagName == 'stdin':
116
            # standard input
117
            case.set_stdin(getTextData(child))
118
        elif child.tagName == 'file':
119
            # file
120
            filename = child.getAttribute('name')
121
            if filename == '':
122
                raise ParseException("File without name in case %s" %case_name)
123
            case.add_file(filename, getTextData(child))
124
        elif child.tagName == 'var':
125
            # global variable
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':
132
            # function argument
133
            arg_val = child.getAttribute('value')
134
            arg_name = child.getAttribute('name')
135
            if arg_name == '': arg_name = None
136
            
137
            if not arg_val:
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))
148
149
    return case
150
                
1029 by dcoles
Tutorial Service: Ported the tutorial service to the console so that all
151
def parse_exercise_file(fileobj, console, exercise_num=1):
513 by stevenbird
test/test_framework/*, exercises/sample/*
152
    """ Parse an xml exercise file and return a testsuite for that exercise """
661 by drtomc
tutorialservice: log submitted attempts to the database.
153
    dom = parse(fileobj)
512 by stevenbird
Renaming of problems to exercises (initial commit).
154
513 by stevenbird
test/test_framework/*, exercises/sample/*
155
    # get exercise
512 by stevenbird
Renaming of problems to exercises (initial commit).
156
    count = 0
513 by stevenbird
test/test_framework/*, exercises/sample/*
157
    exercise = None
512 by stevenbird
Renaming of problems to exercises (initial commit).
158
    for child in dom.childNodes:
513 by stevenbird
test/test_framework/*, exercises/sample/*
159
        if child.nodeType == child.ELEMENT_NODE and child.tagName == 'exercise':
512 by stevenbird
Renaming of problems to exercises (initial commit).
160
            count += 1
513 by stevenbird
test/test_framework/*, exercises/sample/*
161
            if count == exercise_num:
162
                exercise = child
512 by stevenbird
Renaming of problems to exercises (initial commit).
163
                break
164
513 by stevenbird
test/test_framework/*, exercises/sample/*
165
    if exercise == None:
166
        raise ParseException("Not enough exercises")
512 by stevenbird
Renaming of problems to exercises (initial commit).
167
168
    # get name
513 by stevenbird
test/test_framework/*, exercises/sample/*
169
    exercise_name = exercise.getAttribute('name')
170
    if not exercise_name:
171
        raise ParseException('Exercise name not supplied')
172
1029 by dcoles
Tutorial Service: Ported the tutorial service to the console so that all
173
    exercise_suite = TestSuite(exercise_name, console)
512 by stevenbird
Renaming of problems to exercises (initial commit).
174
175
    # get solution and include info
513 by stevenbird
test/test_framework/*, exercises/sample/*
176
    for child in exercise.childNodes:
512 by stevenbird
Renaming of problems to exercises (initial commit).
177
        if child.nodeType != child.ELEMENT_NODE:
178
            continue
179
        if child.tagName == 'solution':
513 by stevenbird
test/test_framework/*, exercises/sample/*
180
            exercise_suite.add_solution(getTextData(child))
512 by stevenbird
Renaming of problems to exercises (initial commit).
181
        elif child.tagName == 'include':
513 by stevenbird
test/test_framework/*, exercises/sample/*
182
            exercise_suite.add_include_code(getTextData(child))
512 by stevenbird
Renaming of problems to exercises (initial commit).
183
        elif child.tagName == 'case':
1029 by dcoles
Tutorial Service: Ported the tutorial service to the console so that all
184
            exercise_suite.add_case(getCaseData(child, console))
512 by stevenbird
Renaming of problems to exercises (initial commit).
185
513 by stevenbird
test/test_framework/*, exercises/sample/*
186
    return exercise_suite
512 by stevenbird
Renaming of problems to exercises (initial commit).
187