source: tracwysiwygplugin/0.12/tests/testunit.js

Last change on this file was 10724, checked in by Jun Omae, 12 years ago

Improved test-case counter in testunit.js.

File size: 6.7 KB
Line 
1TracWysiwyg.TestUnit = function() {
2    this.cases = {};
3    this.assertCounts = {};
4    this.current = null;
5};
6
7(function() {
8    var prototype = TracWysiwyg.TestUnit.prototype;
9
10    prototype.inspect = function(value) {
11        var type = typeof value;
12        switch (type) {
13        case "string":
14            return value.replace(/[\u0000-\u001f\\\u007f\ufffe\uffff]/g, function(m) {
15                var code = m.charCodeAt(0);
16                switch (code) {
17                case 9:  return "\\t";
18                case 10: return "\\n";
19                case 11: return "\\v";
20                case 12: return "\\f";
21                case 13: return "\\r";
22                case 92: return "\\\\";
23                }
24                return "\\u" + (0x10000 + code).toString(16).substring(1);
25            });
26            break;
27        case "object":
28        case "function":
29            if (value instanceof RegExp) {
30                return value.toString();
31            }
32        }
33        return "{%}".replace("%", type) + value.toString();
34    };
35
36    prototype.fragment = function() {
37        var start = 0;
38        var arg = arguments[0];
39        var d;
40        if (arg.nodeType != 9) {
41            d = document;
42        }
43        else {
44            d = arg;
45            start = 1;
46        }
47        var fragment = d.createDocumentFragment();
48        var length = arguments.length;
49        for (var i = start; i < length; i++) {
50            fragment.appendChild(arguments[i]);
51        }
52        return fragment;
53    };
54
55    prototype.element = function(tag) {
56        var start = 0;
57        var arg = arguments[start++];
58        var d, tag;
59        if (typeof arg == "string") {
60            d = document;
61            tag = arg;
62        }
63        else {
64            d = arg;
65            tag = arguments[start++];
66        }
67        var element = d.createElement(tag);
68        for (var i = start; i < arguments.length; i++) {
69            arg = arguments[i];
70            switch (typeof arg) {
71            case "object":
72                if (typeof arg.nodeType == "undefined") {
73                    for (var name in arg) {
74                        var value = arg[name];
75                        switch (name) {
76                        case "id":
77                            element.id = value;
78                            break;
79                        case "class": case "className":
80                            element.className = value;
81                            break;
82                        default:
83                            element.setAttribute(name, value);
84                            break;
85                        }
86                    }
87                    continue;
88                }
89                break;
90            case "string":
91                arg = d.createTextNode(arg);
92                break;
93            }
94            element.appendChild(arg);
95        }
96        return element;
97    };
98
99    prototype.text = function() {
100        var start = 0;
101        var arg = arguments[start++];
102        var d, text;
103        if (typeof arg == "string") {
104            d = document;
105            text = arg;
106        }
107        else {
108            d = arg;
109            text = arguments[start++];
110        }
111        return d.createTextNode(text);
112    };
113
114    prototype.$ = function(id) {
115        return typeof id == "string" ? document.getElementById(id) : id;
116    };
117
118    prototype.add = function(name, method) {
119        if (name in this.cases) {
120            throw "'" + name + "' is in use.";
121        }
122        this.cases[name] = method;
123        this.assertCounts[name] = 0;
124    };
125
126    prototype.assertEqual = function(expected, actual, label) {
127        var count = ++this.assertCounts[this.current];
128        if (typeof (expected) == typeof (actual) && expected == actual) {
129            return true;
130        }
131        throw (label || "") + "[" + count + "]\n"
132            + this.inspect(expected) + " (" + expected.length + ")\n"
133            + this.inspect(actual) + " (" + actual.length + ")";
134    };
135
136    prototype.assertMatch = function(pattern, string, label) {
137        var count = ++this.assertCounts[this.current];
138        if (pattern.test(string)) {
139            return true;
140        }
141        throw (label || "") + "[" + count + "]\n"
142            + this.inspect(pattern) + "\n"
143            + this.inspect(string) + " (" + string.length + ")";
144    };
145
146    prototype.run = function() {
147        var self = this
148        var $ = this.$, element = this.element, text = this.text;
149        var d = document;
150        var cases = this.cases;
151        var assertCounts = this.assertCounts;
152        var names = [];
153        for (var name in cases) {
154            names.push(name);
155            assertCounts[name] = 0;
156        }
157
158        var container = $("testunit");
159        var count;
160        if (container) {
161            container.parentNode.removeChild(container);
162        }
163        container = element(
164            "table", { id: "testunit" },
165            element("caption", { id: "testunit.summary" }),
166            element("tbody", { id: "testunit.body" }));
167        d.body.appendChild(container);
168        var body = $("testunit.body");
169        var summary = $("testunit.summary");
170        for (count = 0; count < names.length; count++) {
171            body.appendChild(
172                element("tr",
173                    element("td", names[count]),
174                    element("td", { id: "testcase." + count }, "...")));
175        }
176
177        count = 0;
178        var success = 0;
179        var invoke = function() {
180            if (count >= names.length) {
181                self.current = null;
182                return;
183            }
184
185            var current = names[count];
186            self.current = current;
187            var cell = $("testcase." + count);
188            cell.className = "current";
189            try {
190                cases[current].call(self);
191                cell.className = "success";
192                cell.replaceChild(text("OK"), cell.firstChild);
193                success++;
194            }
195            catch (e) {
196                cell.className = "failure";
197                var message = e.message || e.toString();
198                if (e.stack) {
199                    message = [ message, e.stack ].join("\n\n");
200                }
201                cell.replaceChild(
202                    element("textarea", { id: "testcase." + count + ".textarea",
203                                          rows: message.split("\n").length,
204                                          cols: 80,
205                                          readonly: "readonly" }),
206                    cell.firstChild);
207                $("testcase." + count + ".textarea").value = message;
208            }
209            summary.innerHTML = success + " / " + names.length;
210
211            count++;
212            setTimeout(invoke, 10);
213        };
214
215        invoke();
216    };
217})();
Note: See TracBrowser for help on using the repository browser.