PageRenderTime 128ms CodeModel.GetById 42ms app.highlight 79ms RepoModel.GetById 1ms app.codeStats 1ms

/src/lib/test_framework.js

https://github.com/runeh/dragonfly-stp-1
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}