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