[html] Change instanceof operator to typeof test, since instanceof
[browser-dbus-bridge.git] / html / unit.html
1 <!--
2  Copyright © 2008 Movial Creative Technologies Inc
3  Feel free to use the contents of this file in any way you want
4  If you can make money with it, please contact info@movial.com
5  and you have almost-guaranteed sales position waiting for you!
6  -->
7
8 <html>
9 <head>
10 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
11 <title>test</title>
12 <script type='text/javascript' src='dbus.js'></script>
13 <script type='text/javascript'>
14
15 var n_tests = 0;
16 var good = 0;
17 var bad = 0;
18 var current_test = null;
19
20 function Test(method_name, arg, convert, xfail, signature, variant_signature)
21 {
22   this.method_name = method_name;
23   this.arg = arg;
24   this.convert = convert;
25   this.signature = signature;
26   this.variant_signature = variant_signature;
27   this.xfail = xfail;
28   n_tests++;
29   if (!xfail)
30     n_tests++;
31
32 }
33
34 Test.prototype =
35 {
36   method_name: null,
37   arg: null,
38   convert: null,
39   xfail: false,
40   signature: null,
41   variant_signature: null,
42   signal: null,
43   next: null,
44
45   run: function ()
46   {
47     current_test = null;
48     if (!this.method_name)
49     {
50       alert("Test error: No method name specified!");
51       bad++;
52       return;
53     }
54     if (typeof this.arg != 'boolean' && !this.arg)
55     {
56       alert("Test error: No argument specified!");
57       bad++;
58       return;
59     }
60     var method = dbus.getMethod(dbus.SESSION, 'org.movial.Unit',
61                                 '/org/movial/Unit',
62                                 this.method_name, 'org.movial.Unit', this.signature,
63                                 this);
64     this.signal = dbus.getSignal(dbus.SESSION, 'org.movial.Unit', this.method_name,
65                                 null, null, this);
66     this.signal.onemit = this.onemit;
67
68     // We need to receive replies as we go to get a meaningful report
69     // but do test with async replies too!
70     method.async = false;
71
72     var status = document.getElementById('status');
73
74     var send_arg;
75     if (typeof this.convert === "function")
76     {
77       if (this.convert == dbus.Variant)
78       {
79         send_arg = this.convert(this.variant_signature, this.arg);
80       } else {
81         send_arg = this.convert(this.arg);
82       }
83
84       if (!send_arg)
85       {
86         var color = 'red';
87         if (this.xfail)
88         {
89           color = 'green';
90           good++;
91         } else {
92           bad++;
93         }
94         status.innerHTML += '<p>Result: <span style="color: ' + color + ';">Converting "' + this.arg + '" failed</span>';
95         current_test = this.next;
96         setTimeout(run_next, 10);
97         return;
98       }
99     } else {
100       send_arg = this.arg;
101     }
102
103     method.onreply = this.method_reply;
104     method.onerror = this.error_reply;
105
106     var argstr = get_argstr(this.arg);
107
108     status.innerHTML += '<p>Sending ' + this.method_name + ':<span style="color: blue; padding-left: 1em;">' + argstr + ' of type ' + typeof send_arg + ' with signature ' + this.signature + '</span>';
109
110     this.signal.enabled = !this.xfail;
111     method(send_arg);
112   },
113
114   onemit: function (reply_arg)
115   {
116     var status = document.getElementById('status');
117     status.innerHTML += '<p>Got signal "' + this.method_name + '"';
118     this.signal.enabled = false;
119     this.method_reply(reply_arg);
120     
121     current_test = this.next;
122     setTimeout(run_next, 10);
123     show_results();
124   },
125   
126   method_reply: function (reply_arg)
127   {
128     var status = document.getElementById('status');
129
130     if (this.xfail)
131     {
132       status.innerHTML += '<p style="margin-top: -0.5em"><span style="color:red; padding-left: 1em;">This test should have failed, but did not!</span>';
133       bad++;
134       current_test = this.next;
135       setTimeout(run_next, 10);
136       show_results();
137       return;
138     }
139     
140     var color = 'green';
141     if (!is_equal(this.arg, reply_arg))
142       color = 'red';
143
144     var argstr = get_argstr(reply_arg);
145
146     if (color == 'red')
147     {
148       bad++;
149     } else {
150       good++;
151     }
152     
153     status.innerHTML += '<p style="margin-top: -0.5em">Result: <span style="color: ' + color + '; padding-left: 1em;">' + argstr + ', ' + typeof reply_arg + '</span>';
154
155     show_results();
156   },
157
158   error_reply: function (error_name, error_message)
159   {
160     var status = document.getElementById('status');
161
162     this.signal.enabled = false;
163
164     if (this.xfail)
165     {
166       status.innerHTML += '<p style="color: green;">Expected failure:';
167       good++;
168     } else {
169       status.innerHTML += '<p style="color: red;">' + error_name + ':';
170       bad++;
171     }
172     status.innerHTML += '<span style="color: red; padding-left: 1em;">' + error_message + '</span>';
173
174     current_test = this.next;
175     setTimeout(run_next, 10);
176     show_results();
177   }
178
179 };
180
181 function get_argstr(arg)
182 {
183   var argstr;
184
185   if (arg instanceof Array || arg instanceof Object)
186   {
187       var first = true;
188       argstr = '['
189       for (var propname in arg)
190       {
191         if (first) {
192             first = false;
193         } else {
194             argstr += ", ";
195         }
196         argstr += propname + ":" + get_argstr(arg[propname]);
197       }
198       argstr += ']';
199   } else {
200       if (typeof arg == 'boolean')
201       {
202         argstr = arg.toString();
203       } else if (arg) {
204         argstr = arg.toString();
205       } else {
206         argstr = '';
207       }
208   }
209
210   return argstr;
211 }
212
213 function is_equal(a, b)
214 {
215   if ((a instanceof Array && b instanceof Array)
216     || (a instanceof Object && b instanceof Object))
217   {
218     for (var i in a)
219     {
220       if (!is_equal(a[i], b[i]))
221       {
222         return false;
223       }
224     }
225
226   } else if (a != b) {
227     return false;
228   }
229   
230   return true;
231 }
232
233 function run_next()
234 {
235   if (current_test) {
236     current_test.run();
237     return;
238   }
239
240   var status = document.getElementById('status');
241   status.innerHTML += "<p>Ending test...";
242   var end = dbus.getMethod(dbus.SESSION, 'org.movial.Unit',
243                                 '/org/movial/Unit',
244                                 "end", 'org.movial.Unit');
245   end();
246   show_results();
247 }
248
249 function show_results()
250 {
251   var results = document.getElementById('results');
252   results.innerHTML = '<p>Total of ' + n_tests + ' tests, <span style="color: green">passed ' + good + '</span>, <span style="color:red">failed ' + bad + '</span>, unknown ' + (n_tests - good - bad) + ", " + Math.round((good/n_tests)*100) + '% success rate';
253 }
254
255 var tests = new Array();
256
257 function do_unit()
258 {
259   var status = document.getElementById('status');
260   
261   if (!window.dbus)
262   {
263     status.innerHTML += "<p>Browser D-Bus Bridge not available, cannot run tests.";
264     return;
265   }
266
267   setTimeout(show_results, 1000);
268   
269   status.innerHTML += "<p>Starting test...";
270   var start = dbus.getMethod(dbus.SESSION, 'org.movial.Unit',
271                                 '/org/movial/Unit',
272                                 "start", 'org.movial.Unit');
273   start();
274
275   var i = 0;
276
277   tests[i++] = new Test('Boolean', true, null, false);
278   tests[i++] = new Test('Boolean', true, null, false, 'b');
279
280   tests[i++] = new Test('Int16', 32767, dbus.Int16, false);
281   tests[i++] = new Test('Int16', 32767, null, true);
282   tests[i++] = new Test('Int16', 32767, dbus.Int16, false, 'n');
283   tests[i++] = new Test('Int16', 32767, null, false, 'n');
284
285   tests[i++] = new Test('Int32', 2147483647, dbus.Int32, false);
286   tests[i++] = new Test('Int32', 2147483647, null, true);
287   tests[i++] = new Test('Int32', 2147483647, dbus.Int32, false, 'i');
288   tests[i++] = new Test('Int32', 2147483647, null, false, 'i');
289
290   // There's problems with the (u)int64 types since doubles can't hold
291   // large enough values accurately.
292   tests[i++] = new Test('Int64', 17179869176, dbus.Int64, false);
293   tests[i++] = new Test('Int64', 17179869176, null, true);
294   tests[i++] = new Test('Int64', 17179869176, dbus.Int64, false, 'x');
295   tests[i++] = new Test('Int64', 17179869176, null, false, 'x');
296
297   tests[i++] = new Test('UInt16', 32767, dbus.UInt16, false);
298   tests[i++] = new Test('UInt16', 32767, null, true);
299   tests[i++] = new Test('UInt16', 32767, dbus.UInt16, false, 'q');
300   tests[i++] = new Test('UInt16', 32767, null, false, 'q');
301
302   tests[i++] = new Test('UInt32', 2147483647, dbus.UInt32, false);
303   tests[i++] = new Test('UInt32', 2147483647, null, true);
304   tests[i++] = new Test('UInt32', 2147483647, dbus.UInt32, false, 'u');
305   tests[i++] = new Test('UInt32', 2147483647, null, false, 'u');
306
307   tests[i++] = new Test('UInt64', 17179869176, dbus.UInt64, false);
308   tests[i++] = new Test('UInt64', 17179869176, null, true);
309   tests[i++] = new Test('UInt64', 17179869176, dbus.UInt64, false, 't');
310   tests[i++] = new Test('UInt64', 17179869176, null, false, 't');
311
312   tests[i++] = new Test('Double', 1024.1024, null, false);
313   tests[i++] = new Test('Double', 1024.1024, null, false, 'd');
314
315   tests[i++] = new Test('Byte', 1, dbus.Byte, false);
316   tests[i++] = new Test('Byte', 1, null, true);
317   tests[i++] = new Test('Byte', 1, dbus.Byte, false, 'y');
318   tests[i++] = new Test('Byte', 1, null, false, 'y');
319
320   tests[i++] = new Test('String', "abc åäö", null, false);
321   tests[i++] = new Test('String', "abc åäö", null, false, 's');
322
323   tests[i++] = new Test('ObjectPath', "/org/movial/Unit", dbus.ObjectPath, false);
324   tests[i++] = new Test('ObjectPath', "/org/movial/Unit", null, true);
325   tests[i++] = new Test('ObjectPath', "/org/movial/Unit", dbus.ObjectPath, false, 'o');
326   tests[i++] = new Test('ObjectPath', "I'm invalid object path", dbus.ObjectPath, true);
327   tests[i++] = new Test('ObjectPath', "/not//valid/either", dbus.ObjectPath, true);
328
329   tests[i++] = new Test('Signature', "sib", dbus.Signature, false);
330   tests[i++] = new Test('Signature', "sib", null, true);
331   tests[i++] = new Test('Signature', "sib", dbus.Signature, false, 'g');
332   tests[i++] = new Test('Signature', "sib", null, false, 'g');
333
334   tests[i++] = new Test("Array", ["a", "b", "äöÄÖ"], null, false, null);
335   tests[i++] = new Test("Array", [1, 2, 3], null, false, null);
336   tests[i++] = new Test("Array", ["a", "b", "äöÄÖ"], null, false, 'as');
337   tests[i++] = new Test("Array", [1, 2, 3], null, false, 'ai');
338
339   var dict = new Object();
340   dict["abc åäö"] = "abc åäö";
341   tests[i++] = new Test("Dict", dict, null, false, 'a{ss}');
342
343   var dict = new Object();
344   dict["test"] = [100.0, 2.0, 3000.0];
345   tests[i++] = new Test("Dict", dict, null, false, 'a{sad}');
346
347   var dict = new Object();
348   dict["test"] = [100, 2, 3000];
349   tests[i++] = new Test("Dict", dict, null, false, 'a{sai}');
350
351   var dict = new Object();
352   var array = new Array("abc", "def", "åäö");
353   dict["abc åäö"] = array;
354   tests[i++] = new Test("Dict", dict, null, false, 'a{sas}');
355
356   var dict = new Object();
357   var dict2 = new Object();
358   dict2["abc"] = "åäö";
359   dict["åäö"] = dict2;
360   tests[i++] = new Test("Dict", dict, null, false, 'a{sa{ss}}');
361
362   var dict = new Object();
363   var dict2 = new Object();
364   dict2["åäö"] = ["abc", "def", "åäö"];
365   dict["abc"] = dict2;
366   tests[i++] = new Test("Dict", dict, null, false, 'a{sa{sas}}');
367
368   // Test for very deep container structure
369   var deep = new Object();
370   var deep_sig = "a{s";
371   function add_dict(o, d, depth)
372   {
373     o[0] = new Object();
374     deep_sig += "a{s";
375     if (d == depth)
376     {
377       o[0]["abc"] = "åäö";
378       deep_sig += "s}";
379       return;
380     }
381     add_array(o[0], d + 1, depth);
382     deep_sig += "}";
383   }
384   function add_array(o, d, depth)
385   {
386     o["abc"] = new Array();
387     deep_sig += "a";
388     if (d == depth)
389     {
390       o["abc"][0] = "åäö";
391       deep_sig += "s";
392       return;
393     }
394     add_dict(o["abc"], d + 1, depth);
395   }
396
397   add_array(deep, 0, 20);
398   deep_sig += "}";
399   tests[i++] = new Test("Dict", deep, null, false, deep_sig);
400
401   tests[i++] = new Test("Variant", "woot", null, false, 'v');
402   tests[i++] = new Test("Variant", ["woot", "bar"], null, false, 'v');
403
404   var dict = new Object();
405   dict["abc åäö"] = "abc åäö";
406   var dict2 = new Object();
407   dict2["def"] = "bleb";
408   tests[i++] = new Test("Variant", [dict, dict2], null, false, 'v');
409
410   var struct = new Array("abc åäö", 1004);
411   var struct2 = new Array("def", [42, 1004, 105]);
412   var dict = new Object();
413   dict["abc åäö"] = struct2;
414
415   tests[i++] = new Test("Struct", struct, null, false, '(si)');
416   tests[i++] = new Test("Array", [struct, struct2], null, false, 'a(sv)');
417   tests[i++] = new Test("Dict", dict, null, false, 'a{s(sv)}');
418
419   for (var j = 0; j < i-1; j++)
420   {
421     tests[j].next = tests[j+1]
422   }
423   current_test = tests[0];
424   run_next();
425
426 }
427
428 </script>
429 </head>
430 <body onload='do_unit();'>
431 <div><a href="javascript:window.location.reload();">Run again</a> <a href="http://google.fi">Leave the page</a></div>
432 <div id='results' style='border: solid blue 0.1em; padding: 1em; margin: 1em;'></div>
433 <div id='status' style='border: dashed black 0.1em; padding: 1em;'></div>
434
435 </body>
436 </html>
437