/src/lib/test_framework.js
JavaScript | 448 lines | 365 code | 31 blank | 52 comment | 57 complexity | 76ab860b4e9a6fc0b67b230aaa733c7e MD5 | raw file
1/**
2 * (This file was autogenerated by hob)
3 *
4 * @fileoverview
5 * fixme: add fileoverview
6 */
7
8window.cls || ( window.cls = {} );
9
10/**
11 * @constructor
12 */
13
14window.cls.TestFramework = function()
15{
16 /**
17 * class to inspect and test the scope interface
18 *
19 * the class expects the following markup:
20 *
21 * <ul id="window-list"></ul> optional
22 *
23 * <ul id="service-list">
24 * <li>Scope</li>
25 * <li>WindowManager</li>
26 * <li>EcmascriptDebugger</li>
27 * <li>HttpLogger</li>
28 * etc
29 * </ul>
30 *
31 * <ul id="command-list"></ul>
32 *
33 * <ul id="event-list"></ul>
34 *
35 * <div id="message-container"></div>
36 *
37 * the two methods `get_bound_click_handler`
38 * and `get_bound_change_handler` must be set to
39 * an appropriated event listeners
40 *
41 */
42
43 /* interface */
44
45 this.get_bound_click_handler = function(){};
46 this.get_bound_change_handler = function(){};
47 /**
48 * to clear the log entries
49 */
50 this.clear_log = function(){};
51 this.rebuild_last_state = function(){};
52
53 this.rebuild_last_state = function(){};
54
55 /* privat */
56
57 this._selected_service = "";
58 this._status_map = cls.ServiceBase.get_status_map();
59 this._event_map = cls.ServiceBase.get_event_map();
60 this._service_descriptions = null;
61
62 const INDENT = " ", RESPONSE = 2;
63
64 this._get_indent = function(count)
65 {
66 var ret = "";
67 while(count-- > 0)
68 {
69 ret += INDENT;
70 }
71 return ret;
72 }
73
74
75 this._pretty_print_payload_item = function(indent, name, definition, item)
76 {
77 return (
78 this._get_indent(indent) +
79 name + ': ' + (
80 item === null && "null" ||
81 "message" in definition && "\n" +
82 this._pretty_print_payload(item, definition["message"], indent + 1) ||
83 "enum" in definition && item in definition["enum"]["numbers"] && (definition["enum"]["numbers"][item] + " (" + item + ")") ||
84 "type" in definition && definition["type"] == 11 /*bool*/ && (item ? "true" : "false") ||
85 typeof item == "string" && "\"" + item + "\"" ||
86 item));
87 }
88
89 this._pretty_print_payload = function(payload, definitions, indent)
90 {
91 var
92 ret = [],
93 item = null,
94 i = 0,
95 definition = null,
96 j = 0;
97
98 //# TODO message: self
99 if (definitions)
100 {
101 for (; i < payload.length; i++)
102 {
103 item = payload[i];
104 if (item === null)
105 {
106 item = [];
107 }
108 if (definition = definitions[i])
109 {
110 if (definition["q"] == "repeated")
111 {
112 ret.push(this._get_indent(indent) + definition['name'] + ':');
113 for( j = 0; j < item.length; j++)
114 {
115 ret.push(this._pretty_print_payload_item(
116 indent + 1,
117 definition['name'].replace("List", ""),
118 definition,
119 item[j]));
120 }
121 }
122 else
123 {
124 ret.push(this._pretty_print_payload_item(
125 indent,
126 definition['name'],
127 definition,
128 item))
129 }
130 }
131 else
132 {
133 throw Error("PrettyPrintError. Probably invalid message. " +
134 "payload: " + JSON.stringify(payload));
135 }
136 }
137 return ret.join("\n")
138 }
139 return "";
140 }
141
142 // handle a command response
143 this._handle_response = function(status, message, service, command)
144 {
145 this._last_message = Array.prototype.slice.call(arguments, 0);
146 var response = document.getElementById('message-response');
147 if(response)
148 {
149 response.parentNode.removeChild(response);
150 }
151 response =
152 document.getElementById('message-container').
153 appendChild(document.createElement('pre'));
154 response.id = 'message-response';
155 service = this._dashed_name(service);
156 var command_id = this._event_map[service].indexOf('handle' + command);
157 var definitions =
158 window.message_maps[service] &&
159 window.message_maps[service][command_id] &&
160 window.message_maps[service][command_id][RESPONSE] ||
161 null;
162 if (status != 0) // Use the error structure if we received an error response
163 definitions = window.package_map["com.opera.stp"]["Error"];
164 var payload = "";
165 try
166 {
167 payload = (cookies.get('pretty-print-message') == 'true' && definitions ?
168 this._pretty_print_payload(message, definitions, 2) :
169 JSON.stringify(message));
170 }
171 catch (e)
172 {
173 payload = JSON.stringify(message);
174 }
175 response.textContent =
176 "response:\n status: " +
177 this._status_map[status] + "\n" +
178 " payload: \n" +
179 payload;
180 }
181
182 // to highlight the selected element in a list
183 this._update_selected = function(container, target)
184 {
185 var selected = container && container.getElementsByClassName('selected')[0];
186 if(selected)
187 {
188 selected.className = selected.className.replace(/ ?selected/, '');
189 }
190 if(target)
191 {
192 target.className += (target.className ? ' ' : '') + 'selected';
193 }
194 }
195
196 // to upadte the Command and Evenet List
197 this._update_list = function(name, list, target)
198 {
199 var list_ele = document.getElementById(name.toLowerCase() + '-list-container');
200 list_ele.innerHTML =
201 "<h2>" + name + " List</h2><ul id='" + name.toLowerCase() + "-list'>" +
202 list.map(this._list_item).join("") +
203 "</ul>";
204 }
205
206 // callback to display a message definition
207 this._show_def = function(xhr, context)
208 {
209 context.pre.innerHTML = xhr.responseText;
210 }
211
212 // to re-select entries of the Service or Command List
213 this._reselect_element = function(/* list of names */)
214 {
215 var
216 name = '',
217 i = 0,
218 j = 0,
219 last_selected = '',
220 lis = null,
221 li = null;
222
223 for( ; name = arguments[i]; i++)
224 {
225 if(last_selected = cookies.get(name))
226 {
227 lis = document.getElementById(name).getElementsByTagName('li');
228 for( j = 0; ( li = lis[j] ) && li.textContent != last_selected; j++);
229 if(li)
230 {
231 this._click_handler({target: li});
232 }
233 }
234 }
235 }
236
237 // to re-select the last selected service and command or event
238 // and display the according message definitions
239 this.rebuild_last_state = function()
240 {
241 this._reselect_element('service-list', 'command-list');
242 }
243
244 // basic helpers
245 // map argument
246 this._list_item = function(name)
247 {
248 return "<li>" + name + "</li>";
249 }
250
251 this._dashed_name = function(name)
252 {
253 for ( var cur = '', i = 0, ret = ''; cur = name[i]; i++)
254 {
255 ret += /[A-Z]/.test(cur) && ( i ? '-' : '' ) + cur.toLowerCase() || cur;
256 }
257 return ret;
258 }
259
260 this._make_service_descriptions = function()
261 {
262 var
263 map = window.message_maps,
264 service_name = '',
265 command_id = '',
266 servive = null,
267 commands = null,
268 events = null;
269
270 this._service_descriptions = {commands:{}, events: {}};
271 for (service_name in map)
272 {
273 service = map[service_name];
274 service_name = window.app.helpers.dash_to_class_name(service_name);
275 commands = this._service_descriptions.commands[service_name] = [];
276 events = this._service_descriptions.events[service_name] = [];
277 for (command_id in service)
278 (1 in service[command_id] && commands || events).push(service[command_id].name);
279 commands.sort();
280 events.sort();
281 }
282 }
283
284 // generic click event handler
285 this._click_handler = function(event)
286 {
287 var target = event.target;
288 if (!this._service_descriptions)
289 {
290 this._make_service_descriptions();
291 }
292 if(!this._doc_base_uri)
293 {
294 this._doc_base_uri =
295 document.getElementsByTagName('base')[0] ?
296 document.baseURI :
297 './';
298 }
299 while (target && !target.id && (target = target.parentNode));
300 if (target)
301 {
302 switch (target.id)
303 {
304 case 'window-list':
305 {
306 this._update_selected(target.parentNode, event.target);
307 windows.set_debug_context(parseInt(event.target.getAttribute('data-window-id')));
308 break;
309 }
310 case 'service-list':
311 {
312 this._update_selected(target, event.target);
313 document.getElementById('message-container').innerHTML = "";
314 this._selected_service = event.target.textContent
315 this._update_list('Command', this._service_descriptions.commands[this._selected_service], target);
316 this._update_list('Event', this._service_descriptions.events[this._selected_service], target);
317 cookies.set('service-list', this._selected_service, 2*60*60*1000);
318 break;
319 }
320 case 'command-list':
321 {
322 this._update_selected(target, event.target);
323 this._update_selected(document.getElementById('event-list'));
324 var message_container = document.getElementById('message-container');
325 message_container.innerHTML =
326 "<h2>Command " + event.target.textContent + "</h2>" +
327 "<h3>command</h3><pre class='definition'></pre>" +
328 "<textarea rows='10' id='proto-message'>[]</textarea>" +
329 "<p class='right-aligned'><input type='button' value='send' data-service='" + this._selected_service + "'" +
330 " data-command='" + event.target.textContent +
331 "' id = 'test-send-command' ></p>" +
332 "<h3>response</h3><pre class='definition'></pre>" +
333 "<p class='right-aligned'><label>pretty print message " +
334 "<input type='checkbox'" +
335 (cookies.get('pretty-print-message') == 'true' ? " checked='checked' " : "" ) +
336 " id='pretty-print-message'>" +
337 "</label></p>";
338 var pres = message_container.getElementsByTagName('pre');
339 var service = window.services[this._dashed_name(this._selected_service)];
340 if (service)
341 {
342 service = this._selected_service + '.' + service.version;
343 new XMLHttpRequest().loadResource(
344 this._doc_base_uri + 'defs/' + service + '.commands.' + event.target.textContent + '.def',
345 this._show_def,
346 {'pre': pres[0]}
347 )
348 new XMLHttpRequest().loadResource(
349 this._doc_base_uri + 'defs/' + service + '.responses.' + event.target.textContent + '.def',
350 this._show_def,
351 {'pre': pres[1]}
352 )
353 }
354 cookies.set('command-list', event.target.textContent, 2*60*60*1000);
355 break;
356 }
357 case 'event-list':
358 {
359 this._update_selected(target, event.target);
360 this._update_selected(document.getElementById('command-list'));
361 var message_container = document.getElementById('message-container');
362 message_container.innerHTML =
363 "<h2>Event " + event.target.textContent + "</h2>" +
364 "<pre class='definition'></pre>";
365 var pres = message_container.getElementsByTagName('pre');
366 var service = window.services[this._dashed_name(this._selected_service)];
367 if (service)
368 {
369 service = this._selected_service + '.' + service.version;
370 new XMLHttpRequest().loadResource(
371 this._doc_base_uri + 'defs/' + service + '.events.' + event.target.textContent + '.def',
372 this._show_def,
373 {'pre': pres[0]}
374 );
375 }
376 break;
377 }
378 case 'test-send-command':
379 {
380 this._send_command(target);
381 break;
382 }
383 case 'clear-log':
384 {
385 document.getElementById('log-container').firstElementChild.textContent = "";
386 break;
387 }
388 }
389 }
390 }
391
392 this._change_handler = function(event)
393 {
394 switch(event.target.id)
395 {
396 case 'pretty-print-message':
397 {
398 cookies.set('pretty-print-message', event.target.checked && 'true' || 'false');
399 if(this._last_message)
400 {
401 this._handle_response.apply(this, this._last_message);
402 }
403 break;
404 }
405 }
406 }
407
408 /* implementation */
409 this._send_command = function(target)
410 {
411 var service = target.getAttribute('data-service');
412 var command = target.getAttribute('data-command');
413 var response = document.getElementById('message-response');
414 if(response)
415 {
416 response.parentNode.removeChild(response);
417 }
418 try
419 {
420 var message = eval('(' + document.getElementById('proto-message').value + ')');
421 var tag = tagManager.set_callback(this, this._handle_response, [service, command]);
422 services[this._dashed_name(service)]['request' + command](tag, message);
423 }
424 catch(e)
425 {
426 alert('not a valid message');
427 };
428 }
429
430 this.get_bound_click_handler = function()
431 {
432 var self = this;
433 return function(event)
434 {
435 self._click_handler(event);
436 }
437 }
438
439 this.get_bound_change_handler = function()
440 {
441 var self = this;
442 return function(event)
443 {
444 self._change_handler(event);
445 }
446 }
447
448}