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

« back to all changes in this revision

Viewing changes to ivle/webapp/tutorial/test/parse_exercise.py

  • Committer: William Grant
  • Date: 2009-02-23 23:47:02 UTC
  • mfrom: (1099.1.211 new-dispatch)
  • Revision ID: grantw@unimelb.edu.au-20090223234702-db4b1llly46ignwo
Merge from lp:~ivle-dev/ivle/new-dispatch.

Pretty much everything changes. Reread the setup docs. Backup your databases.
Every file is now in a different installed location, the configuration system
is rewritten, the dispatch system is rewritten, URLs are different, the
database is different, worksheets and exercises are no longer on the
filesystem, we use a templating engine, jail service protocols are rewritten,
we don't repeat ourselves, we have authorization rewritten, phpBB is gone,
and probably lots of other things that I cannot remember.

This is certainly the biggest commit I have ever made, and hopefully
the largest I ever will.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2008 The University of Melbourne
 
2
# Copyright (C) 2007-2009 The University of Melbourne
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
18
18
# Module: parse_exercise
19
19
# Author: Dilshan Angampitiya
20
20
#         Steven Bird (revisions)
21
 
# Date:   24/1/2008
22
 
 
23
 
"""
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.
28
 
"""
29
 
 
30
 
from xml.dom.minidom import *
 
21
 
 
22
"""
 
23
This file was hacked apart by Nick
 
24
"""
 
25
 
31
26
from TestFramework import *
32
27
 
33
 
DEFAULT_TEST_TYPE = 'norm'
34
 
DEFAULT_CASE_TYPE = 'match'
35
 
 
36
 
class ParseException(Exception):
37
 
    " Error when parsing the xml exercise file "
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)
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)
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
 
 
102
 
def getCaseData(caseNode, console):
103
 
    """ Create a TestCase instance from test case xml data
104
 
    """
105
 
    
106
 
    case_name = caseNode.getAttribute('name')
107
 
    function = caseNode.getAttribute('function')
108
 
    if function == '': function = None
109
 
    case = TestCase(console, case_name, function)
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
 
                
151
 
def parse_exercise_file(fileobj, console, exercise_num=1):
152
 
    """ Parse an xml exercise file and return a testsuite for that exercise """
153
 
    dom = parse(fileobj)
154
 
 
155
 
    # get exercise
156
 
    count = 0
157
 
    exercise = None
158
 
    for child in dom.childNodes:
159
 
        if child.nodeType == child.ELEMENT_NODE and child.tagName == 'exercise':
160
 
            count += 1
161
 
            if count == exercise_num:
162
 
                exercise = child
163
 
                break
164
 
 
165
 
    if exercise == None:
166
 
        raise ParseException("Not enough exercises")
167
 
 
168
 
    # get name
169
 
    exercise_name = exercise.getAttribute('name')
170
 
    if not exercise_name:
171
 
        raise ParseException('Exercise name not supplied')
172
 
 
173
 
    exercise_suite = TestSuite(exercise_name, console)
174
 
 
175
 
    # get solution and include info
176
 
    for child in exercise.childNodes:
177
 
        if child.nodeType != child.ELEMENT_NODE:
178
 
            continue
179
 
        if child.tagName == 'solution':
180
 
            exercise_suite.add_solution(getTextData(child))
181
 
        elif child.tagName == 'include':
182
 
            exercise_suite.add_include_code(getTextData(child))
183
 
        elif child.tagName == 'case':
184
 
            exercise_suite.add_case(getCaseData(child, console))
185
 
 
186
 
    return exercise_suite
187
 
 
 
28
def parse_exercise_file(exercise, console):
 
29
    """ Parse an xml exercise file and return a testsuite for that exercise """
 
30
    # Generate the TestSuite for the given exercise
 
31
    return TestSuite(exercise, console)
 
32