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

« back to all changes in this revision

Viewing changes to www/media/tutorial/tutorial.js

  • Committer: mattgiuca
  • Date: 2008-01-25 05:38:02 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:312
Full client-side testing - functional.

tutorial.js: Added all the code necessary to send the request, parse the
response, and generate the DOM nodes to display the result to the user.

tutorial.css: Added list styles.
Added media/images/tutorial with pass/fail/exception icons.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
function submitproblem(problemid, filename)
29
29
{
30
30
    /* Get the source code the student is submitting */
31
 
    problemdiv = document.getElementById(problemid);
32
 
    problembox = problemdiv.getElementsByTagName("textarea")[0];
33
 
    code = problembox.value;
34
 
    alert("code = \"" + code + "\"\nproblem = \"" + filename + "\"\n"
35
 
        + "action = \"test\"");
 
31
    var problemdiv = document.getElementById(problemid);
 
32
    var problembox = problemdiv.getElementsByTagName("textarea")[0];
 
33
    var code = problembox.value;
 
34
 
 
35
    var args = {"code": code, "problem": filename, "action": "test"};
 
36
 
 
37
    /* Send the form as multipart/form-data, since we are sending a whole lump
 
38
     * of Python code, it should be treated like a file upload. */
 
39
    var xhr = ajax_call("tutorialservice", "", args, "POST",
 
40
        "multipart/form-data");
 
41
    var testresponse = JSON.parse(xhr.responseText);
 
42
    handle_testresponse(problemdiv, testresponse);
 
43
}
 
44
 
 
45
/** Given a problem div, return the testoutput div which is its child.
 
46
 * (The div which is its child whose class is "testoutput".
 
47
 */
 
48
function get_testoutput(problemdiv)
 
49
{
 
50
    var childs = problemdiv.childNodes;
 
51
    var i;
 
52
    var testoutput;
 
53
    for (i=0; i<childs.length; i++)
 
54
        if (childs[i].nodeType == problemdiv.ELEMENT_NODE &&
 
55
            childs[i].getAttribute("class") == "testoutput")
 
56
            return childs[i];
 
57
    return null;
 
58
}
 
59
 
 
60
/** Given a response object (JSON-parsed object), displays the result of the
 
61
 * test to the user. This modifies the given problemdiv's children.
 
62
 */
 
63
function handle_testresponse(problemdiv, testresponse)
 
64
{
 
65
    var testoutput = get_testoutput(problemdiv);
 
66
    var i, j;
 
67
    var ul;
 
68
    var case_ul;
 
69
    if (testoutput == null) return;     /* should not happen */
 
70
    dom_removechildren(testoutput);
 
71
 
 
72
    ul = document.createElement("ul");
 
73
    testoutput.appendChild(ul);
 
74
 
 
75
    if ("critical_error" in testresponse)
 
76
    {
 
77
        /* Only one error - and it's bad.
 
78
         * Just print and stop */
 
79
        ul.appendChild(create_response_item("critical",
 
80
            testresponse.critical_error.name,
 
81
            testresponse.critical_error.detail));
 
82
        return;
 
83
    }
 
84
 
 
85
    for (i=0; i<testresponse.cases.length; i++)
 
86
    {
 
87
        var testcase = testresponse.cases[i];
 
88
        if ("exception" in testcase)
 
89
        {
 
90
            /* User's code threw an exception */
 
91
            fail_li = create_response_item("fail", testcase.name);
 
92
            ul.appendChild(fail_li);
 
93
            /* Create a sub-ul to display the failing cases. */
 
94
            case_ul = document.createElement("ul");
 
95
            fail_li.appendChild(case_ul);
 
96
            case_ul.appendChild(create_response_item("exception",
 
97
                testcase.exception.name, testcase.exception.detail));
 
98
        }
 
99
        else if (testcase.passed)
 
100
        {
 
101
            /* All parts of the test case passed. Just report the overall case
 
102
             * passing. */
 
103
            ul.appendChild(create_response_item("pass", testcase.name));
 
104
        }
 
105
        else
 
106
        {
 
107
            var fail_li = create_response_item("fail", testcase.name);
 
108
            ul.appendChild(fail_li);
 
109
            /* Create a sub-ul to display the failing cases. */
 
110
            case_ul = document.createElement("ul");
 
111
            fail_li.appendChild(case_ul);
 
112
            
 
113
            for (j=0; j<testcase.parts.length; j++)
 
114
            {
 
115
                var part = testcase.parts[j];
 
116
                if (part.passed)
 
117
                {
 
118
                    case_ul.appendChild(create_response_item("pass",
 
119
                        part.description));
 
120
                }
 
121
                else
 
122
                {
 
123
                    case_ul.appendChild(create_response_item("fail",
 
124
                        part.description, part.error_message));
 
125
                }
 
126
            }
 
127
        }
 
128
    }
 
129
}
 
130
 
 
131
/* DOM creators for test case response elements */
 
132
 
 
133
/** Create a <li> element for the result of a test case.
 
134
 * type: "pass", "fail", "exception" or "critical"
 
135
 * detail should be null for passing cases.
 
136
 * For exceptions and crits, "desc" is the exception name,
 
137
 * detail is the message.
 
138
 */
 
139
function create_response_item(type, desc, detail)
 
140
{
 
141
    var crit = false;
 
142
    if (type == "critical")
 
143
    {
 
144
        /* Crits look like exceptions, but are slightly different */
 
145
        crit = true;
 
146
        type = "exception";
 
147
    }
 
148
    var li = document.createElement("li");
 
149
    li.setAttribute("class", type);
 
150
    var b = document.createElement("b");
 
151
    var text = type[0].toUpperCase() + type.substr(1) + ":";
 
152
    b.appendChild(document.createTextNode(text));
 
153
    li.appendChild(b);
 
154
    if (type == "pass")
 
155
        text = desc;
 
156
    else if (type == "fail")
 
157
        text = desc + (detail == null ? "" : ":");
 
158
    else if (type == "exception")
 
159
    {
 
160
        if (crit)
 
161
            text = "Your code could not be executed, "
 
162
                + "due to the following error:";
 
163
        else
 
164
            text = "The following exception occured "
 
165
                + "while running your code:";
 
166
    }
 
167
    li.appendChild(document.createTextNode(" " + text));
 
168
    if (type == "pass" || (type == "fail" && detail == null))
 
169
        return li;
 
170
 
 
171
    /* Non-passes, display the error message */
 
172
    li.appendChild(document.createElement("br"));
 
173
    if (type == "exception")
 
174
    {
 
175
        b = document.createElement("b");
 
176
        b.appendChild(document.createTextNode(desc + ":"));
 
177
        li.appendChild(b);
 
178
    }
 
179
    li.appendChild(document.createTextNode(detail));
 
180
    return li;
36
181
}