<commit_before>function createSourceLinks() {
    $('.method_details_list .source_code').
        before("[View source]");
    $('.toggleSource').toggle(function() {
       $(this).parent().nextAll('.source_code').slideDown(100);
       $(this).text("Hide source");
    },
    function() {
        $(this).parent().nextAll('.source_code').slideUp(100);
        $(this).text("View source");
    });
}

function createDefineLinks() {
    var tHeight = 0;
    $('.defines').after(" more...");
    $('.toggleDefines').toggle(function() {
        tHeight = $(this).parent().prev().height();
        $(this).prev().show();
        $(this).parent().prev().height($(this).parent().height());
        $(this).text("(less)");
    },
    function() {
        $(this).prev().hide();
        $(this).parent().prev().height(tHeight);
        $(this).text("more...");
    });
}

function createFullTreeLinks() {
    var tHeight = 0;
    $('.inheritanceTree').toggle(function() {
        tHeight = $(this).parent().prev().height();
        $(this).parent().toggleClass('showAll');
        $(this).text("(hide)");
        $(this).parent().prev().height($(this).parent().height());
    },
    function() {
        $(this).parent().toggleClass('showAll');
        $(this).parent().prev().height(tHeight);
        $(this).text("show all");
    });
}

function fixBoxInfoHeights() {
    $('dl.box dd.r1, dl.box dd.r2').each(function() {
       $(this).prev().height($(this).height());
    });
}

function searchFrameLinks() {
  $('.full_list_link').click(function() {
    toggleSearchFrame(this, $(this).attr('href'));
    return false;
  });
}

function toggleSearchFrame(id, link) {
  var frame = $('#search_frame');
  $('#search a').removeClass('active').addClass('inactive');
  if (frame.attr('src') == link && frame.css('display') != "none") {
    frame.slideUp(100);
    $('#search a').removeClass('active inactive');
  }
  else {
    $(id).addClass('active').removeClass('inactive');
    frame.attr('src', link).slideDown(100);
  }
}

function linkSummaries() {
  $('.summary_signature').click(function() {
    document.location = $(this).find('a').attr('href');
  });
}

function framesInit() {
  if (hasFrames) {
    document.body.className = 'frames';
    $('#menu .noframes a').attr('href', document.location);
    window.top.document.title = $('html head title').text();
  }
  else {
    $('#menu .noframes a').text('frames').attr('href', framesUrl);
  }
}

function keyboardShortcuts() {
  if (window.top.frames.main) return;
  $(document).keypress(function(evt) {
    if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) return;
    if (typeof evt.target !== "undefined" &&
        (evt.target.nodeName == "INPUT" ||
        evt.target.nodeName == "TEXTAREA")) return;
    switch (evt.charCode) {
      case 67: case 99:  $('#class_list_link').click(); break;  // 'c'
      case 77: case 109: $('#method_list_link').click(); break; // 'm'
      case 70: case 102: $('#file_list_link').click(); break;   // 'f'
      default: break;
    }
  });
}

function summaryToggle() {
  $('.summary_toggle').click(function() {
    localStorage.summaryCollapsed = $(this).text();
    $(this).text($(this).text() == "collapse" ? "expand" : "collapse");
    var next = $(this).parent().parent().nextAll('ul.summary').first();
    if (next.hasClass('compact')) {
      next.toggle();
      next.nextAll('ul.summary').first().toggle();
    }
    else if (next.hasClass('summary')) {
      var list = $('
');
      list.html(next.html());
      list.find('.summary_desc, .note').remove();
      list.find('a').each(function() {
        $(this).html($(this).find('strong').html());
        $(this).parent().html($(this)[0].outerHTML);
      });
      next.before(list);
      next.toggle();
    }
    return false;
  });
  if (localStorage) {
    if (localStorage.summaryCollapsed == "collapse") $('.summary_toggle').click();
    else localStorage.summaryCollapsed = "expand";
  }
}

function fixOutsideWorldLinks() {
  $('a').each(function() {
    if (window.location.host != this.host) this.target = '_parent';
  });
}

function generateTOC() {
  if ($('#filecontents').length === 0) return;
  var _toc = $('

');
  var show = false;
  var toc = _toc;
  var counter = 0;
  var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];
  var i;
  if ($('#filecontents h1').length > 1) tags.unshift('h1');
  for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; }
  var lastTag = parseInt(tags[0][1], 10);
  $(tags.join(', ')).each(function() {
    if ($(this).parents('.method_details .docstring').length != 0) return;
    if (this.id == "filecontents") return;
    show = true;
    var thisTag = parseInt(this.tagName[1], 10);
    if (this.id.length === 0) {
      var proposedId = $(this).attr('toc-id');
      if (typeof(proposedId) != "undefined") this.id = proposedId;
      else {
        var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_');
        if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; }
        this.id = proposedId;
      }
    }
    if (thisTag > lastTag) {
      for (i = 0; i < thisTag - lastTag; i++) {
        var tmp = $('
'); toc.append(tmp); toc = tmp;
      }
    }
    if (thisTag < lastTag) {
      for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent();
    }
    var title = $(this).attr('toc-title');
    if (typeof(title) == "undefined") title = $(this).text();
    toc.append('
' + title + '
');
    lastTag = thisTag;
  });
  if (!show) return;
  html = '

Table of Contents (left)

';
  $('#content').prepend(html);
  $('#toc').append(_toc);
  $('#toc .hide_toc').toggle(function() {
    $('#toc .top').slideUp('fast');
    $('#toc').toggleClass('hidden');
    $('#toc .title small').toggle();
  }, function() {
    $('#toc .top').slideDown('fast');
    $('#toc').toggleClass('hidden');
    $('#toc .title small').toggle();
  });
  $('#toc .float_toc').toggle(function() {
    $(this).text('float');
    $('#toc').toggleClass('nofloat');
  }, function() {
    $(this).text('left');
    $('#toc').toggleClass('nofloat');
  });
}

$(framesInit);
$(createSourceLinks);
$(createDefineLinks);
$(createFullTreeLinks);
$(fixBoxInfoHeights);
$(searchFrameLinks);
$(linkSummaries);
$(keyboardShortcuts);
$(summaryToggle);
$(fixOutsideWorldLinks);
$(generateTOC);<commit_msg>Collapse/expand all summary lists when button on any list is clicked<commit_after>function createSourceLinks() {
    $('.method_details_list .source_code').
        before("[View source]");
    $('.toggleSource').toggle(function() {
       $(this).parent().nextAll('.source_code').slideDown(100);
       $(this).text("Hide source");
    },
    function() {
        $(this).parent().nextAll('.source_code').slideUp(100);
        $(this).text("View source");
    });
}

function createDefineLinks() {
    var tHeight = 0;
    $('.defines').after(" more...");
    $('.toggleDefines').toggle(function() {
        tHeight = $(this).parent().prev().height();
        $(this).prev().show();
        $(this).parent().prev().height($(this).parent().height());
        $(this).text("(less)");
    },
    function() {
        $(this).prev().hide();
        $(this).parent().prev().height(tHeight);
        $(this).text("more...");
    });
}

function createFullTreeLinks() {
    var tHeight = 0;
    $('.inheritanceTree').toggle(function() {
        tHeight = $(this).parent().prev().height();
        $(this).parent().toggleClass('showAll');
        $(this).text("(hide)");
        $(this).parent().prev().height($(this).parent().height());
    },
    function() {
        $(this).parent().toggleClass('showAll');
        $(this).parent().prev().height(tHeight);
        $(this).text("show all");
    });
}

function fixBoxInfoHeights() {
    $('dl.box dd.r1, dl.box dd.r2').each(function() {
       $(this).prev().height($(this).height());
    });
}

function searchFrameLinks() {
  $('.full_list_link').click(function() {
    toggleSearchFrame(this, $(this).attr('href'));
    return false;
  });
}

function toggleSearchFrame(id, link) {
  var frame = $('#search_frame');
  $('#search a').removeClass('active').addClass('inactive');
  if (frame.attr('src') == link && frame.css('display') != "none") {
    frame.slideUp(100);
    $('#search a').removeClass('active inactive');
  }
  else {
    $(id).addClass('active').removeClass('inactive');
    frame.attr('src', link).slideDown(100);
  }
}

function linkSummaries() {
  $('.summary_signature').click(function() {
    document.location = $(this).find('a').attr('href');
  });
}

function framesInit() {
  if (hasFrames) {
    document.body.className = 'frames';
    $('#menu .noframes a').attr('href', document.location);
    window.top.document.title = $('html head title').text();
  }
  else {
    $('#menu .noframes a').text('frames').attr('href', framesUrl);
  }
}

function keyboardShortcuts() {
  if (window.top.frames.main) return;
  $(document).keypress(function(evt) {
    if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) return;
    if (typeof evt.target !== "undefined" &&
        (evt.target.nodeName == "INPUT" ||
        evt.target.nodeName == "TEXTAREA")) return;
    switch (evt.charCode) {
      case 67: case 99:  $('#class_list_link').click(); break;  // 'c'
      case 77: case 109: $('#method_list_link').click(); break; // 'm'
      case 70: case 102: $('#file_list_link').click(); break;   // 'f'
      default: break;
    }
  });
}

function summaryToggle() {
  $('.summary_toggle').click(function() {
    if (localStorage) {
      localStorage.summaryCollapsed = $(this).text();
    }
    $('.summary_toggle').each(function() {
      $(this).text($(this).text() == "collapse" ? "expand" : "collapse");
      var next = $(this).parent().parent().nextAll('ul.summary').first();
      if (next.hasClass('compact')) {
        next.toggle();
        next.nextAll('ul.summary').first().toggle();
      }
      else if (next.hasClass('summary')) {
        var list = $('
');
        list.html(next.html());
        list.find('.summary_desc, .note').remove();
        list.find('a').each(function() {
          $(this).html($(this).find('strong').html());
          $(this).parent().html($(this)[0].outerHTML);
        });
        next.before(list);
        next.toggle();
      }
    });
    return false;
  });
  if (localStorage) {
    if (localStorage.summaryCollapsed == "collapse") {
      $('.summary_toggle').first().click();
    }
    else localStorage.summaryCollapsed = "expand";
  }
}

function fixOutsideWorldLinks() {
  $('a').each(function() {
    if (window.location.host != this.host) this.target = '_parent';
  });
}

function generateTOC() {
  if ($('#filecontents').length === 0) return;
  var _toc = $('

');
  var show = false;
  var toc = _toc;
  var counter = 0;
  var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];
  var i;
  if ($('#filecontents h1').length > 1) tags.unshift('h1');
  for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; }
  var lastTag = parseInt(tags[0][1], 10);
  $(tags.join(', ')).each(function() {
    if ($(this).parents('.method_details .docstring').length != 0) return;
    if (this.id == "filecontents") return;
    show = true;
    var thisTag = parseInt(this.tagName[1], 10);
    if (this.id.length === 0) {
      var proposedId = $(this).attr('toc-id');
      if (typeof(proposedId) != "undefined") this.id = proposedId;
      else {
        var proposedId = $(this).text().replace(/[^a-z0-9-]/ig, '_');
        if ($('#' + proposedId).length > 0) { proposedId += counter; counter++; }
        this.id = proposedId;
      }
    }
    if (thisTag > lastTag) {
      for (i = 0; i < thisTag - lastTag; i++) {
        var tmp = $('
'); toc.append(tmp); toc = tmp;
      }
    }
    if (thisTag < lastTag) {
      for (i = 0; i < lastTag - thisTag; i++) toc = toc.parent();
    }
    var title = $(this).attr('toc-title');
    if (typeof(title) == "undefined") title = $(this).text();
    toc.append('
' + title + '
');
    lastTag = thisTag;
  });
  if (!show) return;
  html = '

Table of Contents (left)

';
  $('#content').prepend(html);
  $('#toc').append(_toc);
  $('#toc .hide_toc').toggle(function() {
    $('#toc .top').slideUp('fast');
    $('#toc').toggleClass('hidden');
    $('#toc .title small').toggle();
  }, function() {
    $('#toc .top').slideDown('fast');
    $('#toc').toggleClass('hidden');
    $('#toc .title small').toggle();
  });
  $('#toc .float_toc').toggle(function() {
    $(this).text('float');
    $('#toc').toggleClass('nofloat');
  }, function() {
    $(this).text('left');
    $('#toc').toggleClass('nofloat');
  });
}

$(framesInit);
$(createSourceLinks);
$(createDefineLinks);
$(createFullTreeLinks);
$(fixBoxInfoHeights);
$(searchFrameLinks);
$(linkSummaries);
$(keyboardShortcuts);
$(summaryToggle);
$(fixOutsideWorldLinks);
$(generateTOC);<|endoftext|>


<commit_before>
/*!
 * Ext JS Connect
 * Copyright(c) 2010 Ext JS, Inc.
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var MemoryStore = require('./session/memory').MemoryStore,
    utils = require('./../utils');

/**
 * Setup session store with the given `options`.
 *
 * Options:
 *
 *   - `store`         Session store instance
 *   - `fingerprint`   Custom fingerprint hashing function
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function session(options){
    options = options || {};

    // Default memory store
    store = options.store || new MemoryStore;

    // Default fingerprint hashing function
    store.fingerprint = options.fingerprint || function(sid, req){
        return sid
            + req.socket.remoteAddress
            + (req.headers['user-agent'] || '');
    };

    return function session(req, res, next){
        // Expose store
        req.sessionStore = store;

        // Generate session id when not present
        req.sessionId = req.cookies[store.key] || utils.uid();

        if (req.cookies) {
            // Commit session
            var writeHead = res.writeHead;
            res.writeHead = function(status, headers){
                headers = headers || {};
                res.writeHead = writeHead;
                // TODO: async? ...
                store.commit(req);
                // TODO: abstract
                store.cookie.expires = new Date(+new Date() + store.maxAge);
                headers['Set-Cookie'] = utils.serializeCookie(store.key, req.session.id, store.cookie);
                return res.writeHead(status, headers);
            };

            // Fetch session
            store.fetch(req, function(err, sess){
                req.session = sess || store.createSession();
                req.session.touch();
                next(err);
            });
        } else {
            next();
        }
    }
};<commit_msg>Added req.sessionHash<commit_after>
/*!
 * Ext JS Connect
 * Copyright(c) 2010 Ext JS, Inc.
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var MemoryStore = require('./session/memory').MemoryStore,
    utils = require('./../utils');

/**
 * Setup session store with the given `options`.
 *
 * Options:
 *
 *   - `store`         Session store instance
 *   - `fingerprint`   Custom fingerprint hashing function
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function session(options){
    options = options || {};

    // Default memory store
    store = options.store || new MemoryStore;

    // Default fingerprint hashing function
    store.fingerprint = options.fingerprint || function(sid, req){
        return sid
            + req.socket.remoteAddress
            + (req.headers['user-agent'] || '');
    };

    return function session(req, res, next){
        // Expose store
        req.sessionStore = store;

        // Generate session id when not present
        req.sessionId = req.cookies[store.key] || utils.uid();
        req.sessionHash = store.fingerprint(req.sessionId, req);

        if (req.cookies) {
            // Commit session
            var writeHead = res.writeHead;
            res.writeHead = function(status, headers){
                headers = headers || {};
                res.writeHead = writeHead;
                // TODO: async? ...
                store.commit(req);
                // TODO: abstract
                store.cookie.expires = new Date(+new Date() + store.maxAge);
                headers['Set-Cookie'] = utils.serializeCookie(store.key, req.session.id, store.cookie);
                return res.writeHead(status, headers);
            };

            // Fetch session
            store.fetch(req, function(err, sess){
                req.session = sess || store.createSession();
                req.session.touch();
                next(err);
            });
        } else {
            next();
        }
    }
};<|endoftext|>


<commit_before>define(['jquery', 'rz_core', 'view/selection'],
function($, rz_core, selection) {

function get_graph_view(element)
{
    var dict = rz_core.root_element_id_to_graph_view;

    while (undefined !== element && null !== element && undefined === dict[element.id]) {
        element = element.parentElement;
    }
    return element !== undefined && element !== null ? dict[element.id] : undefined;
}

function install() {
    document.body.onkeydown = function(e) {
        var key = ((e.key && String(e.key))
                   || (e.charCode && String.fromCharCode(e.charCode))
                   || (e.which && String.fromCharCode(e.which))).toLowerCase(),
            handled = false,
            graph_view = get_graph_view(e.target);

        if (e.altKey && e.ctrlKey && 'i' === key) {
            $('#textanalyser').focus();
        }
        if (e.altKey && e.ctrlKey && 'o' === key) {
            search.focus();
        }
        if (e.ctrlKey && 'a' === key && e.target === document.body) {
            selection.select_nodes(rz_core.main_graph.nodes());
            handled = true;
        }
        if (e.ctrlKey && 'z' === key && e.target.nodeName !== 'INPUT') {
            // TODO: rz_core.main_graph.undo();
        }
        // SVG elements cannot handle any keys directly - pass the key to them in this case
        if (undefined !== graph_view) {
            graph_view.keyboard_handler(e);
        }
        if (handled) {
            e.preventDefault();
            e.stopPropagation();
        }
    };
}
return {
        install: install
       };
}
);
<commit_msg>client: add F6 shortcut to zoom to selection<commit_after>define(['jquery', 'rz_core', 'view/selection'],
function($, rz_core, selection) {

function get_graph_view(element)
{
    var dict = rz_core.root_element_id_to_graph_view;

    while (undefined !== element && null !== element && undefined === dict[element.id]) {
        element = element.parentElement;
    }
    return element !== undefined && element !== null ? dict[element.id] : undefined;
}

function install() {
    document.body.onkeydown = function(e) {
        var key = ((e.key && String(e.key))
                   || (e.charCode && String.fromCharCode(e.charCode))
                   || (e.which && String.fromCharCode(e.which))).toLowerCase(),
            handled = false,
            graph_view = get_graph_view(e.target);

        if (e.altKey && e.ctrlKey && 'i' === key) {
            $('#textanalyser').focus();
        }
        if (e.keyIdentifier === 'F6') {
            rz_core.main_graph_view.nodes__user_visible(selection.selected_nodes(), true);
            handled = true;
        }
        if (e.altKey && e.ctrlKey && 'o' === key) {
            search.focus();
            handled = true;
        }
        if (e.ctrlKey && 'a' === key && e.target === document.body) {
            selection.select_nodes(rz_core.main_graph.nodes());
            handled = true;
        }
        if (e.ctrlKey && 'z' === key && e.target.nodeName !== 'INPUT') {
            // TODO: rz_core.main_graph.undo();
        }
        // SVG elements cannot handle any keys directly - pass the key to them in this case
        if (undefined !== graph_view) {
            graph_view.keyboard_handler(e);
        }
        if (handled) {
            e.preventDefault();
            e.stopPropagation();
        }
    };
}
return {
        install: install
       };
}
);
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var $ = require('jquery');
var idGenerator = new (require('../../util/IdGenerator'))('ov');

/**
 * @class
 *
 * A plugin that add an API that allows to add HTML overlays.
 * The HTML overlays will be add to the html container.
 *
 * Translations on the canvas will also take place on the overlays.
 * Changes in zoom level will have no effect to the overlay.
 *
 * @param {eventBus} The event bus
 * @param {canvas} Instance of the canvas service
 */
function Overlays(eventBus, canvas, elementRegistry) {
  var self = this;

  var ZOOM_LOW_LIMIT  = 0.5;
  var ZOOM_UPPER_LIMIT  = 2.0;

  this._OVERLAY_PREFIX = 'OL-';
  this._overlays = {};
  this._overlayTypes = {};
  this._elementRegistry = elementRegistry;
  this._canvas = canvas;
  this._setOverlayPosition = setOverlayPosition;
  this._setOverlayVisible = setOverlayVisible;
  this._idGenerator = idGenerator;

  function setOverlaysPosition(viewBox) {
    _.forEach(self._overlays, function(overlay) {
      setOverlayPosition(overlay, viewBox);
    });
  }

  function setOverlaysVisible() {
    var zoom = canvas.zoom();

    _.forEach(self._overlays, function(overlay) {
      setOverlayVisible(overlay, zoom);
    });
  }

  function setOverlayVisible(overlay, zoom) {
    var m = zoom < (overlay.config.minZoom || ZOOM_LOW_LIMIT);
    var u = zoom > (overlay.config.maxZoom || ZOOM_UPPER_LIMIT);

    if(m || u) {
      overlay.overlayContainer.style.display = 'none';
    } else {
      overlay.overlayContainer.style.display = '';
    }
  }

  function setOverlayPosition(overlay, viewBox) {
    var top = overlay.shape.x;
    var left = overlay.shape.y;

    var a = viewBox.scale || 1;
    var d = viewBox.scale || 1;
    var e = viewBox.x || 0;
    var f = viewBox.y || 0;

    var matrixString = 'matrix(' +
      '1,0,0,1,' +
      (e + (top * a)) + ',' +
      (f + (left * d)) + ')';

    overlay.overlayContainer.style.transform = matrixString;
  }

  function init() {
    self._overlayParentContainer = canvas.getContainer();

    /**
     * @event overlaycontainer.init - Overlay types should register for this event
     *                                 and should register itself at the overlay service
     */
    eventBus.fire('overlaycontainer.init', {});
  }

  // Register event handler
  eventBus.on('canvas.init', function() {
    init();
  });

  eventBus.on('canvas.viewbox.changed', function(event) {
    setOverlaysPosition(event.viewbox);
    setOverlaysVisible();
  });

  eventBus.on('shape.changed', function(event) {
    var overlay;
    _.forEach(self._overlays, function(_overlay) {
      if(_overlay.shape.id === event.element.id) {
        overlay = _overlay;
      }
    });
    if(overlay) {
      setOverlayPosition(overlay, canvas.viewBox());
    }
  });

  eventBus.on('shape.removed', function(event) {
    var overlay;
    _.forEach(self._overlays, function(_overlay) {
      if(_overlay.shape.id === event.element.id) {
        overlay = _overlay;
      }
    });
    if(!!overlay) {
      self.removeOverlay(overlay.id);
    }
  });
  return this;
}

Overlays.prototype._createOverlayInstanceContainer = function(id) {

  var overlayContainer = $('
', {
    class: 'overlay-container',
    id: id
  }).insertBefore($(this._canvas.getContainer()).find( 'svg' ));

  overlayContainer.css({
    position: 'absolute'
  });

  return overlayContainer.get(0);
};

Overlays.prototype.getOverlays = function() {
  return _.clone(this._overlays);
};

/**
 *
 * @param overlayName - Name of the overlay that should be attached to the element
 * @param shape - The target diagram node
 * @param overlayConfig - specific config fot this overlay type
 */
Overlays.prototype.addOverlayToElement = function(overlayName, shape, overlayConfig) {

  var id = this._idGenerator.next();
  _.extend(overlayConfig, {
    id: id
  });

  var overlayContainer = this._createOverlayInstanceContainer(id);

  var position = this._canvas.viewbox();

  //special handling for untyped HTML overlays
  if(overlayName === 'html') {
    var html = $(overlayConfig.html);
    $(overlayContainer).append(html);
    if(overlayConfig.x) {
      position.x = overlayConfig.x;
      position.y = overlayConfig.y;
      position.scale = overlayConfig.scale;
    }
  } else {
    this._overlayTypes[overlayName].attach(overlayContainer, overlayConfig);
  }
  this._overlays[id] = {
    id: id,
    overlayContainer: overlayContainer,
    shape: shape,
    config: overlayConfig
  };

  this._setOverlayPosition(this._overlays[id], this._canvas.viewbox());
  this._setOverlayVisible(this._overlays[id], this._canvas.zoom());

  return id;
};

/**
 * Adds an simple HTML overlay to an element.
 *
 * @param {Shape} shape - Attach overly to this shape
 * @param {Object} overlayConfig - { html: '
Test
' }
 */
Overlays.prototype.addOverlay = function(shape, overlayConfig) {
  return this.addOverlayToElement('html', shape, overlayConfig);
};

Overlays.prototype.registerOverlayType = function(overlayType) {
  if (this._overlayTypes[overlayType.name]) {
    throw new Error('Overlay type already registered.');
  }
  if (!overlayType) {
    throw new Error('Overlay type is undefined.');
  }

  this._overlayTypes[overlayType.name] = overlayType;
};

Overlays.prototype.removeOverlay = function(id) {
  $('#' + id).remove();
  delete this._overlays[id];
};

Overlays.$inject = [ 'eventBus', 'canvas', 'elementRegistry' ];

module.exports = Overlays;<commit_msg>docs(overlays): improve docs<commit_after>'use strict';

var _ = require('lodash');
var $ = require('jquery');
var idGenerator = new (require('../../util/IdGenerator'))('ov');

/**
 * @class
 *
 * A plugin that add an API that allows to add HTML overlays to diagram Shapes.
 *
 * Translations on the canvas will also take place on the overlays.
 * Changes in zoom level have no effect to the overlay.
 *
 * @param {eventBus} The event bus
 * @param {canvas} Instance of the canvas service
 */
function Overlays(eventBus, canvas, elementRegistry) {
  var self = this;

  var ZOOM_LOW_LIMIT  = 0.5;
  var ZOOM_UPPER_LIMIT  = 2.0;

  this._OVERLAY_PREFIX = 'OL-';
  this._overlays = {};
  this._overlayTypes = {};
  this._elementRegistry = elementRegistry;
  this._canvas = canvas;
  this._setOverlayPosition = setOverlayPosition;
  this._setOverlayVisible = setOverlayVisible;
  this._idGenerator = idGenerator;

  function setOverlaysPosition(viewBox) {
    _.forEach(self._overlays, function(overlay) {
      setOverlayPosition(overlay, viewBox);
    });
  }

  function setOverlaysVisible() {
    var zoom = canvas.zoom();

    _.forEach(self._overlays, function(overlay) {
      setOverlayVisible(overlay, zoom);
    });
  }

  function setOverlayVisible(overlay, zoom) {
    var m = zoom < (overlay.config.minZoom || ZOOM_LOW_LIMIT);
    var u = zoom > (overlay.config.maxZoom || ZOOM_UPPER_LIMIT);

    if(m || u) {
      overlay.overlayContainer.style.display = 'none';
    } else {
      overlay.overlayContainer.style.display = '';
    }
  }

  function setOverlayPosition(overlay, viewBox) {
    var top = overlay.shape.x;
    var left = overlay.shape.y;

    var a = viewBox.scale || 1;
    var d = viewBox.scale || 1;
    var e = viewBox.x || 0;
    var f = viewBox.y || 0;

    var matrixString = 'matrix(' +
      '1,0,0,1,' +
      (e + (top * a)) + ',' +
      (f + (left * d)) + ')';

    overlay.overlayContainer.style.transform = matrixString;
  }

  function init() {
    self._overlayParentContainer = canvas.getContainer();

    /**
     * @event overlaycontainer.init - Overlay types should register for this event
     *                                 and should register itself at the overlay service
     */
    eventBus.fire('overlaycontainer.init', {});
  }

  // Register event handler
  eventBus.on('canvas.init', function() {
    init();
  });

  eventBus.on('canvas.viewbox.changed', function(event) {
    setOverlaysPosition(event.viewbox);
    setOverlaysVisible();
  });

  eventBus.on('shape.changed', function(event) {
    var overlay;
    _.forEach(self._overlays, function(_overlay) {
      if(_overlay.shape.id === event.element.id) {
        overlay = _overlay;
      }
    });
    if(overlay && !overlay.x) {
      setOverlayPosition(overlay, canvas.viewBox());
    }
  });

  eventBus.on('shape.removed', function(event) {
    var overlay;
    _.forEach(self._overlays, function(_overlay) {
      if(_overlay.shape.id === event.element.id) {
        overlay = _overlay;
      }
    });
    if(!!overlay) {
      self.removeOverlay(overlay.id);
    }
  });
  return this;
}

Overlays.prototype._createOverlayInstanceContainer = function(id) {

  var overlayContainer = $('
', {
    class: 'overlay-container',
    id: id
  }).insertBefore($(this._canvas.getContainer()).find( 'svg' ));

  overlayContainer.css({
    position: 'absolute'
  });

  return overlayContainer.get(0);
};

Overlays.prototype.getOverlays = function() {
  return _.clone(this._overlays);
};

/**
 * This API is not stable and maybe changed or removed in later versions.
 *
 * @param overlayName - Name of the overlay that should be attached to the element
 * @param shape - The target diagram node
 * @param overlayConfig - specific config for this overlay type
 */
Overlays.prototype.addOverlayToElement = function(overlayName, shape, overlayConfig) {

  var id = this._idGenerator.next();
  _.extend(overlayConfig, {
    id: id
  });

  var overlayContainer = this._createOverlayInstanceContainer(id);

  var position = this._canvas.viewbox();

  //special handling for untyped HTML overlays
  if(overlayName === 'html') {
    var html = $(overlayConfig.html);
    $(overlayContainer).append(html);
    if(overlayConfig.x) {
      position.x = overlayConfig.x;
      position.y = overlayConfig.y;
      position.scale = this._canvas.viewbox().scale;
    }
  } else {
    this._overlayTypes[overlayName].attach(overlayContainer, overlayConfig);
  }
  this._overlays[id] = {
    id: id,
    overlayContainer: overlayContainer,
    shape: shape,
    config: overlayConfig
  };

  this._setOverlayPosition(this._overlays[id], this._canvas.viewbox());
  this._setOverlayVisible(this._overlays[id], this._canvas.zoom());

  return id;
};

/**
 * Adds a HTML overlay to an element.
 *
 * @param {Shape} shape - Attach overlay to this shape
 * @param {Object} overlayConfig -
{
 *   html: '<div>Test</div>', // String containing valid HTML or a jQuery object
 *   minZoom: 0.2,            // (optional) minimum zoom level until the overlay will hidden
 *   maxZoom: 1.8,            // (optional) maximum zoom level until the overlay will hidden
 *   x:  50,                  // (optional) use x instead of element.position.x
 *   y:  50                   // (optional) use y instead of element.position.y
 * }

 *
 * The property html could be a string or a jQuery object.
 */
Overlays.prototype.addOverlay = function(shape, overlayConfig) {
  return this.addOverlayToElement('html', shape, overlayConfig);
};

Overlays.prototype.registerOverlayType = function(overlayType) {
  if (this._overlayTypes[overlayType.name]) {
    throw new Error('Overlay type already registered.');
  }
  if (!overlayType) {
    throw new Error('Overlay type is undefined.');
  }

  this._overlayTypes[overlayType.name] = overlayType;
};

Overlays.prototype.removeOverlay = function(id) {
  $('#' + id).remove();
  delete this._overlays[id];
};

Overlays.$inject = [ 'eventBus', 'canvas', 'elementRegistry' ];

module.exports = Overlays;<|endoftext|>


<commit_before>/******************************************************************************
* view.js                                                                     *
* Copyright 2013                                                              *
* For details about the copyright holders, see the COPYRIGHT file.            *
* This software is freely distributed under the ISC License.                  *
* For details about the license, see the LICENSE file.                        *
*                                                                             *
* This module provides an API for interacting with the user interface.        *
******************************************************************************/

define([
    "jquery",
    "editor"
], function($) {
    var editor = require('editor');

    var view = {};
    var languages = null;

    var noop = function() {};

/******************************************************************************
* Initialization                                                              *
******************************************************************************/
    var init = function() {
        // never run again
        init = noop;

        editor.fromTextArea($('#code-view')[0]);
    };

    view.initCodeMode = function() {
        // never run again
        view.initCodeMode = codeMode;

        init();
        var select = $('#language_id');
        select.change(function(eventOb) {
            view.setHighlighting(select
								 .children('[value='+selected_lang_id+']')
								 .data('lang'));
        });
        codeMode();
    };

    view.initCommentMode = function() {
        // never run again
        view.initCommentMode = commentMode;

        init();
        commentMode();
    };

/******************************************************************************
* View Modes                                                                  *
******************************************************************************/
    var codeMode = function() {
        $('#code_instructions').show();
        $('#comment_instructions').hide();
        $('#code_controls').show();
        $('#comment_controls').hide();
    };

    var commentMode = function() {
        editor.setOption('readOnly',true);
        $('#code_instructions').hide();
        $('#comment_instructions').show();
        $('#code_controls').hide();
        $('#comment_controls').show();
    };

/******************************************************************************
* Display                                                                     *
******************************************************************************/
    view.displayError = function(err_html) {
        $('#error').html(err_html);
    };

    view.displayCode = function(code) {
        editor.setValue(code.text);
        editor.setHighlighting(code.lang);
    };

    view.displayComments = function(comments_array) {
        for(var i in comments_array) {
            view.displayComment(comments_array[i]);
        }
    };

    view.displayComment = function(comment) {
        // TODO: finish this
    };

/******************************************************************************
* Controls                                                                    *
******************************************************************************/
    view.populateLanguageList = function(langs_ob) {
        view.populateLanguageList = noop;

        langs_array = langs_ob.data;
        var lang_list = $('#lang');
		for(var index in langs_array) {
			var language = langs_array[index];
            if(language.mode) {
			    var option = $('<option>');
			    option.data('lang',index);
			    option.val(index);
			    option.text(language.description);
			    lang_list.append(option);
            }
		}

        lang_list.change(function(eo) {
            //console.dir(eo);
            //console.log(lang_list.val());
            editor.setHighlighting(lang_list.val());
        });
    };

/******************************************************************************
* End                                                                         *
******************************************************************************/
    return view;
});<commit_msg>Removed debug code (I suck)<commit_after>/******************************************************************************
* view.js                                                                     *
* Copyright 2013                                                              *
* For details about the copyright holders, see the COPYRIGHT file.            *
* This software is freely distributed under the ISC License.                  *
* For details about the license, see the LICENSE file.                        *
*                                                                             *
* This module provides an API for interacting with the user interface.        *
******************************************************************************/

define([
    "jquery",
    "editor"
], function($) {
    var editor = require('editor');

    var view = {};
    var languages = null;

    var noop = function() {};

/******************************************************************************
* Initialization                                                              *
******************************************************************************/
    var init = function() {
        // never run again
        init = noop;

        editor.fromTextArea($('#code-view')[0]);
    };

    view.initCodeMode = function() {
        // never run again
        view.initCodeMode = codeMode;

        init();
        var select = $('#language_id');
        select.change(function(eventOb) {
            view.setHighlighting(select
								 .children('[value='+selected_lang_id+']')
								 .data('lang'));
        });
        codeMode();
    };

    view.initCommentMode = function() {
        // never run again
        view.initCommentMode = commentMode;

        init();
        commentMode();
    };

/******************************************************************************
* View Modes                                                                  *
******************************************************************************/
    var codeMode = function() {
        $('#code_instructions').show();
        $('#comment_instructions').hide();
        $('#code_controls').show();
        $('#comment_controls').hide();
    };

    var commentMode = function() {
        editor.setOption('readOnly',true);
        $('#code_instructions').hide();
        $('#comment_instructions').show();
        $('#code_controls').hide();
        $('#comment_controls').show();
    };

/******************************************************************************
* Display                                                                     *
******************************************************************************/
    view.displayError = function(err_html) {
        $('#error').html(err_html);
    };

    view.displayCode = function(code) {
        editor.setValue(code.text);
        editor.setHighlighting(code.lang);
    };

    view.displayComments = function(comments_array) {
        for(var i in comments_array) {
            view.displayComment(comments_array[i]);
        }
    };

    view.displayComment = function(comment) {
        // TODO: finish this
    };

/******************************************************************************
* Controls                                                                    *
******************************************************************************/
    view.populateLanguageList = function(langs_ob) {
        view.populateLanguageList = noop;

        langs_array = langs_ob.data;
        var lang_list = $('#lang');
		for(var index in langs_array) {
			var language = langs_array[index];
            if(language.mode) {
			    var option = $('<option>');
			    option.data('lang',index);
			    option.val(index);
			    option.text(language.description);
			    lang_list.append(option);
            }
		}

        lang_list.change(function(eo) {
            editor.setHighlighting(lang_list.val());
        });
    };

/******************************************************************************
* End                                                                         *
******************************************************************************/
    return view;
});<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var log = require('debug')('broadcast:db-api');

var Team = mongoose.model('Team');
var User = mongoose.model('User');

var async = require('async');

/**
 * Get all teams
 */
exports.allTeams = function allTeams (fn) {
  Team
  .find()
  .exec(function (err, teams) {
    if (err) return log(err), fn(err);

    if (!teams) return log('No teams found – returning null'), fn(null);

    return log('Found teams %s', teams.map(t => t.id)), fn(null, teams);
  });
}

/**
 * Add's `sender` to `reciever`'s accepts if `accepts`, else removes
 */
exports.modifyAccepts = function modifyAccepts (recieverDomain, senderDomain, accepts, fn) {
  Team
  .findOne({domain: recieverDomain})
  .exec(function (err, reciever) {
    if (err) return log(err), fn(err);

    Team
    .findOne({domain: senderDomain})
    .exec(function (err, sender) {
      if (err) return log(err), fn(err);

      if (accepts) {
        // add sender to reciever's accepts
        reciever.accepts.push(sender.id);
      } else {
        // if reciever currently accepts sender, remove sender from reciever's accepts
        if (reicever.accepts.indexOf(sender.id) > -1) {
          reciever.accepts.splice(sender.accepts.indexOf(sender.id), 1);
        }
      }

      reciever.save(function (err) {
        if (err) return log(err), fn(err);

        log('Successfully %s %s to %s\'s accepts', accepts ? 'added' : 'removed', senderDomain, recieverDomain);
        return fn(null, reciever);
      });
    });
  });
}

function promiseModifyAccepts (recieverDomain, senderDomain, accepts) {
  var promise = new Promise((resolve, reject) => {
    exports.modifyAccepts(recieverDomain, senderDomain, accepts, function (err, reciever) {
      if (err) return reject(err);

      return resolve(err);
    });
  });
  return promise;
}

/**
 * Add a new team with data in `team`
 */
exports.addTeam = function addTeam (team, fn) {
  team.accepts = [];

  exports.allTeams(function (err, teams) {
    if (err) return log(err), fn(err);

    teams.forEach(t => {
      team.accepts.push(t.id);
    });

    var newTeam = new Team(team);

    newTeam.save(function (err) {
      if (err) return log(err), fn(err);

      exports.allTeams(function (err, teams) {
        Promise
        .all( teams.map(t => promiseModifyAccepts(t.domain, newTeam.domain, true) ))
        .then(teams => {
          return fn(null, newTeam);
        }).catch(err => {
          if (err) return log(err), fn(err);
        });
      });

    });
  });

}

/**
 * Get the teams that `outTeam` is allowed to send messages to
 */
exports.teamsFor = function (outTeamDomain, fn) {
  exports.allTeams(function (err, teams) {
    if (err) return fn(err);

    var outTeam = teams.filter(function (t) {
      return t.domain == outTeamDomain;
    })[0];

    if (outTeam) var outTeamId = outTeam.id;

    var teamsFor = teams.filter(function (t) {
      return t.accepts.indexOf(outTeamId) > -1;
    });

    log('%s is allowed to send to %s', outTeam.id, teamsFor.map(t => t.id));
    return fn(null, teamsFor);
  });
}

/**
 * Get a particular user
 */
exports.getUser = function getUser (username, fn) {
  User
  .findOne({username: username})
  .exec(function (err, user) {
    if (err) return log(err), fn(err);

    if (!user) return log('User with username %s not found', username), fn(null);

    return fn(null, user);
  });
}

/**
 * Get a particular user, creating one if it doesn't exist
 */
exports.ensureUser = function ensureUser (username, fn) {
  exports.getUser(function (err, user) {
    if (err) return log(err), fn(err);

    if (!user) {
      log('User with username %s not found, creating one...', username);
      var newUser = new User({username: username});
      newUser.save(function (err) {
        if (err) return log(err), fn(err);

        fn(null, newUser);
      });
    }

    return fn(null, user);
  });
}

/**
 * Makes user with username admin
 */
exports.makeUserAdmin = function (username, fn) {
  exports.ensureUser(username, function (err, user) {
    if (err) return fn(err); if (!user) fn(null);

    user.admin = true;
    user.save(function (err, user) {
      if (err) return log(err), fn(err);

      return log('Make %s admin', username), fn(null, user);
    });
  });
}

/**
 * Ban a particular user
 */
exports.modifySend = function (username, canSend, fn) {
  exports.ensureUser(username, function (err, user) {
    if (err) return fn(err); if (!user) fn(null);

    user.send = canSend;
    user.save(function (err, user) {
      if (err) return log(err), fn(err);

      return log('Make user %s\'s send privileges = %s', username, canSend), fn(null, user);
    });
  });
}

<commit_msg>fixed spelling error<commit_after>var mongoose = require('mongoose');
var log = require('debug')('broadcast:db-api');

var Team = mongoose.model('Team');
var User = mongoose.model('User');

var async = require('async');

/**
 * Get all teams
 */
exports.allTeams = function allTeams (fn) {
  Team
  .find()
  .exec(function (err, teams) {
    if (err) return log(err), fn(err);

    if (!teams) return log('No teams found – returning null'), fn(null);

    return log('Found teams %s', teams.map(t => t.id)), fn(null, teams);
  });
}

/**
 * Add's `sender` to `reciever`'s accepts if `accepts`, else removes
 */
exports.modifyAccepts = function modifyAccepts (recieverDomain, senderDomain, accepts, fn) {
  Team
  .findOne({domain: recieverDomain})
  .exec(function (err, reciever) {
    if (err) return log(err), fn(err);

    Team
    .findOne({domain: senderDomain})
    .exec(function (err, sender) {
      if (err) return log(err), fn(err);

      if (accepts) {
        // add sender to reciever's accepts
        reciever.accepts.push(sender.id);
      } else {
        // if reciever currently accepts sender, remove sender from reciever's accepts
        if (reciever.accepts.indexOf(sender.id) > -1) {
          reciever.accepts.splice(sender.accepts.indexOf(sender.id), 1);
        }
      }

      reciever.save(function (err) {
        if (err) return log(err), fn(err);

        log('Successfully %s %s to %s\'s accepts', accepts ? 'added' : 'removed', senderDomain, recieverDomain);
        return fn(null, reciever);
      });
    });
  });
}

function promiseModifyAccepts (recieverDomain, senderDomain, accepts) {
  var promise = new Promise((resolve, reject) => {
    exports.modifyAccepts(recieverDomain, senderDomain, accepts, function (err, reciever) {
      if (err) return reject(err);

      return resolve(err);
    });
  });
  return promise;
}

/**
 * Add a new team with data in `team`
 */
exports.addTeam = function addTeam (team, fn) {
  team.accepts = [];

  exports.allTeams(function (err, teams) {
    if (err) return log(err), fn(err);

    teams.forEach(t => {
      team.accepts.push(t.id);
    });

    var newTeam = new Team(team);

    newTeam.save(function (err) {
      if (err) return log(err), fn(err);

      exports.allTeams(function (err, teams) {
        Promise
        .all( teams.map(t => promiseModifyAccepts(t.domain, newTeam.domain, true) ))
        .then(teams => {
          return fn(null, newTeam);
        }).catch(err => {
          if (err) return log(err), fn(err);
        });
      });

    });
  });

}

/**
 * Get the teams that `outTeam` is allowed to send messages to
 */
exports.teamsFor = function (outTeamDomain, fn) {
  exports.allTeams(function (err, teams) {
    if (err) return fn(err);

    var outTeam = teams.filter(function (t) {
      return t.domain == outTeamDomain;
    })[0];

    if (outTeam) var outTeamId = outTeam.id;

    var teamsFor = teams.filter(function (t) {
      return t.accepts.indexOf(outTeamId) > -1;
    });

    log('%s is allowed to send to %s', outTeam.id, teamsFor.map(t => t.id));
    return fn(null, teamsFor);
  });
}

/**
 * Get a particular user
 */
exports.getUser = function getUser (username, fn) {
  User
  .findOne({username: username})
  .exec(function (err, user) {
    if (err) return log(err), fn(err);

    if (!user) return log('User with username %s not found', username), fn(null);

    return fn(null, user);
  });
}

/**
 * Get a particular user, creating one if it doesn't exist
 */
exports.ensureUser = function ensureUser (username, fn) {
  exports.getUser(function (err, user) {
    if (err) return log(err), fn(err);

    if (!user) {
      log('User with username %s not found, creating one...', username);
      var newUser = new User({username: username});
      newUser.save(function (err) {
        if (err) return log(err), fn(err);

        fn(null, newUser);
      });
    }

    return fn(null, user);
  });
}

/**
 * Makes user with username admin
 */
exports.makeUserAdmin = function (username, fn) {
  exports.ensureUser(username, function (err, user) {
    if (err) return fn(err); if (!user) fn(null);

    user.admin = true;
    user.save(function (err, user) {
      if (err) return log(err), fn(err);

      return log('Make %s admin', username), fn(null, user);
    });
  });
}

/**
 * Ban a particular user
 */
exports.modifySend = function (username, canSend, fn) {
  exports.ensureUser(username, function (err, user) {
    if (err) return fn(err); if (!user) fn(null);

    user.send = canSend;
    user.save(function (err, user) {
      if (err) return log(err), fn(err);

      return log('Make user %s\'s send privileges = %s', username, canSend), fn(null, user);
    });
  });
}

<|endoftext|>


<commit_before>__.core.Functions = {
	/*
	Function: contains
	In support browsers, determines if a function contains a given string / matches a given regex.  Useful to see if a certain variable is used or function is called, particularly for checking if a child class calls a parent class's method.  For unsupported browsers, always returns true to allow them to function (may change this behavior in the future.)

	Parameters:
		argFunction(Function): the function to examine
		argContains(RegExp|String): the string content to search the function for
	*/
	contains:
		//--make sure functions can be tested
		(/xyz/.test(function(){xyz;}))
		? function(argFunction, argContains){
			if(!(argContains instanceof RegExp)){
				argContains = new RegExp(argContains, 'i');
			}
			return argContains.test(argFunction);
		}
		: function(){ return true; }

	/*
	Function: duckPunch
	Duck punch a function with a wrapper, ie create a function that runs the wrapper with the original funciton available inside.  Unshifts the original function into the first parameter for the wrapper, since we cannot close into an already existing function.  Wrapper must shift off first argument as original function to be able to apply to said function.

	Example:
		(start code)
		original = function(argOne, argTwo){
		    console.log('original: ' + argOne + ', ' + argTwo);
		}

		wrapper = function(argOne, argTwo){
			//--take advantage of a nifty aspect of shifting arguments: names arguments adjust to the new 'arguments' object.  Noted @ http://blog.boyet.com/blog/javascriptlessons/javascript-using-the-shift-method-on-the-arguments-array/
		    var originalFunction = Array.prototype.shift.call(arguments);
		    console.log('wrapper pre: ' + argOne + ', ' + argTwo);
		    originalFunction.apply(this, arguments);
		    console.log('wrapper post: ' + argOne + ', ' + argTwo);
		}

		newFunction = __.core.Functions.duckPunch(original, wrapper);

		newFunction('one', 'two');
		(end code)
	*/
	,'duckPunch': function(argFunction, argWrapper){
	    return function(){
	        Array.prototype.unshift.call(arguments, argFunction)
	        argWrapper.apply(this, arguments);
	    }
	}
};
<commit_msg>core/Functions:duckPunch: did not return anything from wrapper !BUGFIX<commit_after>__.core.Functions = {
	/*
	Function: contains
	In support browsers, determines if a function contains a given string / matches a given regex.  Useful to see if a certain variable is used or function is called, particularly for checking if a child class calls a parent class's method.  For unsupported browsers, always returns true to allow them to function (may change this behavior in the future.)

	Parameters:
		argFunction(Function): the function to examine
		argContains(RegExp|String): the string content to search the function for
	*/
	contains:
		//--make sure functions can be tested
		(/xyz/.test(function(){xyz;}))
		? function(argFunction, argContains){
			if(!(argContains instanceof RegExp)){
				argContains = new RegExp(argContains, 'i');
			}
			return argContains.test(argFunction);
		}
		: function(){ return true; }

	/*
	Function: duckPunch
	Duck punch a function with a wrapper, ie create a function that runs the wrapper with the original function available inside.  Unshifts the original function into the first parameter for the wrapper, since we cannot close into an already existing function.  Wrapper must shift off first argument as original function to be able to apply to said function.

	Example:
		(start code)
		original = function(argOne, argTwo){
		    console.log('original: ' + argOne + ', ' + argTwo);
		}

		wrapper = function(argOne, argTwo){
			//--take advantage of a nifty aspect of shifting arguments: names arguments adjust to the new 'arguments' object.  Noted @ http://blog.boyet.com/blog/javascriptlessons/javascript-using-the-shift-method-on-the-arguments-array/
		    var originalFunction = Array.prototype.shift.call(arguments);
		    console.log('wrapper pre: ' + argOne + ', ' + argTwo);
		    originalFunction.apply(this, arguments);
		    console.log('wrapper post: ' + argOne + ', ' + argTwo);
		}

		newFunction = __.core.Functions.duckPunch(original, wrapper);

		newFunction('one', 'two');
		(end code)
	*/
	,'duckPunch': function(argFunction, argWrapper){
	    return function(){
	        Array.prototype.unshift.call(arguments, argFunction)
	        return argWrapper.apply(this, arguments);
	    }
	}
};
<|endoftext|>


<commit_before>'use strict';

describe( 'netiam', function() {

    describe( 'version', function() {
        it( 'should return current library version', function() {
            '0.0.1'.should.be.exactly( '0.0.1' );
        } );
    } );
} );
<commit_msg>chore: netiam: version test is now checking package.json version<commit_after>'use strict';

describe( 'netiam', function() {

    describe( 'version', function() {
        it( 'should return current library version', function() {
            var pkg = require( '../package.json' );

            pkg.version.should.be.exactly( '0.0.1' );
        } );
    } );
} );
<|endoftext|>


<commit_before>var assert = require('assert')

var parser = require('../lib/parser.js')

describe('parser', function () {
  describe('parse', function () {
    it('should return a string', function () {
      assert.equal('string', typeof parser.parse(''))
    })
    it('should return false if there\'s invalid any javascript in the jcss', function () {
      assert.ok(!parser.parse('asdf'))
    })
    it('should take jcss and return css', function () {
      assert.equal('asdf', parser.parse('["a", "s", "d", "f"].forEach(function (value) { css(value) })'))
      assert.equal('div {\n  display: block;\n}\ntroll', parser.parse('div {\n  display: block;\n}\n  css(\'troll\')'))
      assert.equal('div {\
          display: block;\
        }\
        \
        trolltrolltrolltrolltrolltrolltrolltrolltroll', parser.parse('div {\
          display: block;\
        }\
        \
        for(var i = 10; i > 0; i--) {\
          css(\'troll\')\
        }\
        '))
    })
    it('should return false if false is passed to it', function () {
      assert.equal(false, parser.parse(false))
    })
  })

  describe('interpret', function () {
    it('should exec js if the first position is js', function () {
      assert.equal('asdf', parser.interpret(['js', '["a", "s", "d", "f"].forEach(function (value) { css(value) })']))
    })
    it('should return the passed string if the first position is css', function () {
      assert.equal('display: block', parser.interpret(['css', 'display: block']))
    })
  })

  describe('split', function () {
    var testJcss
    var testCss
    var parseReturn
    before(function () {
      testJcss = '\n        div {\n          display: block;\n        }\n\n        css(".class { display: none; }")\n      '
      testCss = {css:  '\n        div {\n          display: block;\n        }',
        js:'\n        css(".class { display: none; }")\n      '}
      parseReturn = parser.split(testJcss)
    })
    it('should return an array of two arrays with the inner array having js or css in the first position and a string at the second', function () {
      assert.equal('object', typeof parseReturn)
      assert.equal(2, parseReturn[0].length)
      assert.ok(parseReturn[0][0] == 'js' || parseReturn[0][0] == 'css')
      assert.equal('string', typeof parseReturn[0][1])
    })
    it('should interpret all line endings before and after css as css', function () {
      assert.equal('\n', parseReturn[0][1][0])
      assert.equal('\n', parseReturn[0][1][parseReturn[0][1].length - 1])
      assert.equal('\n', parseReturn[0][1][parseReturn[0][1].length - 2])
    })
    it('should be able to handle only js or only css', function () {
      assert.equal('css("div{display:block;}")', parser.split('css("div{display:block;}")')[0][1])
      assert.equal('div{display:block;}', parser.split('div{display:block;}')[0][1])
      assert.equal('', parser.split('div{display:block;}')[1][1])
    })
    it('should return false if the passed string is empty', function () {
      assert.equal(false, parser.split(''))
    })
    it('should mark css and js as such', function () {
      assert.equal('        \
        for(var i = 10; i < 0; i--) {\
          css(\'troll\')\
        }\
        ', parser.split('div {\
          display: block;\
        }\
        \
        for(var i = 10; i < 0; i--) {\
          css(\'troll\')\
        }\
        ')[1][1])
    })
  })

  describe('exec', function () {
    it('should return a string', function () {
      assert.equal('string', typeof parser.exec(''))
    })
    it('should return false if the string that is passed isn\'t valid JS.', function () {
      assert.equal(false, parser.exec('yourmum'))
    })
    it('should provide a function `css` to the JS beeing execute', function () {
      assert.equal('display: block', parser.exec('css("display: block")'))
    })
    it('should exec JS', function () {
      assert.equal('asdf', parser.exec('["a", "s", "d", "f"].forEach(function (value) { css(value) })'))
    })
  })
})<commit_msg>Fix a test for parser.parse<commit_after>var assert = require('assert')

var parser = require('../lib/parser.js')

describe('parser', function () {
  describe('parse', function () {
    it('should return a string', function () {
      assert.equal('string', typeof parser.parse(''))
    })
    it('should return false if there\'s invalid any javascript in the jcss', function () {
      assert.ok(!parser.parse('asdf'))
    })
    it('should take jcss and return css', function () {
      assert.equal('asdf', parser.parse('["a", "s", "d", "f"].forEach(function (value) { css(value) })'))
      assert.equal('div {\n  display: block;\n}\ntroll', parser.parse('div {\n  display: block;\n}\n  css(\'troll\')'))
      assert.equal('div {\
          display: block;\
        }\
\
trolltrolltrolltrolltrolltrolltrolltroll', parser.parse('div {\
          display: block;\
        }\
        \
        for(var i = 10; i > 0; i--) {\
          css(\'troll\')\
        }\
        '))
    })
    it('should return false if false is passed to it', function () {
      assert.equal(false, parser.parse(false))
    })
  })

  describe('interpret', function () {
    it('should exec js if the first position is js', function () {
      assert.equal('asdf', parser.interpret(['js', '["a", "s", "d", "f"].forEach(function (value) { css(value) })']))
    })
    it('should return the passed string if the first position is css', function () {
      assert.equal('display: block', parser.interpret(['css', 'display: block']))
    })
  })

  describe('split', function () {
    var testJcss
    var testCss
    var parseReturn
    before(function () {
      testJcss = '\n        div {\n          display: block;\n        }\n\n        css(".class { display: none; }")\n      '
      testCss = {css:  '\n        div {\n          display: block;\n        }',
        js:'\n        css(".class { display: none; }")\n      '}
      parseReturn = parser.split(testJcss)
    })
    it('should return an array of two arrays with the inner array having js or css in the first position and a string at the second', function () {
      assert.equal('object', typeof parseReturn)
      assert.equal(2, parseReturn[0].length)
      assert.ok(parseReturn[0][0] == 'js' || parseReturn[0][0] == 'css')
      assert.equal('string', typeof parseReturn[0][1])
    })
    it('should interpret all line endings before and after css as css', function () {
      assert.equal('\n', parseReturn[0][1][0])
      assert.equal('\n', parseReturn[0][1][parseReturn[0][1].length - 1])
      assert.equal('\n', parseReturn[0][1][parseReturn[0][1].length - 2])
    })
    it('should be able to handle only js or only css', function () {
      assert.equal('css("div{display:block;}")', parser.split('css("div{display:block;}")')[0][1])
      assert.equal('div{display:block;}', parser.split('div{display:block;}')[0][1])
      assert.equal('', parser.split('div{display:block;}')[1][1])
    })
    it('should return false if the passed string is empty', function () {
      assert.equal(false, parser.split(''))
    })
    it('should mark css and js as such', function () {
      assert.equal('        \
        for(var i = 10; i < 0; i--) {\
          css(\'troll\')\
        }\
        ', parser.split('div {\
          display: block;\
        }\
        \
        for(var i = 10; i < 0; i--) {\
          css(\'troll\')\
        }\
        ')[1][1])
    })
  })

  describe('exec', function () {
    it('should return a string', function () {
      assert.equal('string', typeof parser.exec(''))
    })
    it('should return false if the string that is passed isn\'t valid JS.', function () {
      assert.equal(false, parser.exec('yourmum'))
    })
    it('should provide a function `css` to the JS beeing execute', function () {
      assert.equal('display: block', parser.exec('css("display: block")'))
    })
    it('should exec JS', function () {
      assert.equal('asdf', parser.exec('["a", "s", "d", "f"].forEach(function (value) { css(value) })'))
    })
  })
})<|endoftext|>


<commit_before>
/**
 * Test dependencies.
 */

var parser = eio.parser

/**
 * Shortcuts
 */

var encode = parser.encodePacket
  , decode = parser.decodePacket
  , encPayload = parser.encodePayload
  , decPayload = parser.decodePayload

/**
 * Tests.
 */

describe('parser', function () {

  describe('packets', function () {
    describe('basic functionality', function () {
      it('should encode packets as strings', function () {
        expect(encode({ type: 'message', data: 'test' })).to.be.a('string');
      });

      it('should decode packets as objects', function () {
        expect(decode(encode({ type: 'message', data: 'test' }))).to.be.an('object');
      });
    });

    describe('encoding and decoding', function () {
      it('should allow no data', function () {
        expect(decode(encode({ type: 'message' })))
          .to.eql({ type: 'message' });
      });

      it('should encode an open packet', function () {
        expect(decode(encode({ type: 'open', data: '1' })))
          .to.eql({ type: 'open', data: '1' });
      });

      it('should encode a close packet', function () {
        expect(decode(encode({ type: 'close', data: '1' })))
          .to.eql({ type: 'close', data: '1' });
      });

      it('should encode a ping packet', function () {
        expect(decode(encode({ type: 'ping', data: '1' })))
          .to.eql({ type: 'ping', data: '1' });
      });

      it('should encode a pong packet', function () {
        expect(decode(encode({ type: 'pong', data: '1' })))
          .to.eql({ type: 'pong', data: '1' });
      });

      it('should encode a message packet', function () {
        expect(decode(encode({ type: 'message', data: 'aaa' })))
          .to.eql({ type: 'message', data: 'aaa' });
      });

      it('should encode an error packet', function () {
        expect(decode(encode({ type: 'error', data: 'aaa' })))
          .to.eql({ type: 'error', data: 'aaa' });
      });

      it('should encode a noop packet', function () {
        expect(decode(encode({ type: 'noop', data: 'aaa' })))
          .to.eql({ type: 'noop', data: 'aaa' });
      });

      it('should distinguish between empty data and no data', function () {
        var packet = decode(encode({ type: 'message', data: '' }));
        expect(packet.data).to.equal('');

        packet = decode(encode({ type: 'message' }));
        expect(packet.data).to.be(undefined);
      });

      it('should match the encoding format', function () {
        expect(encode({ type: 'message', data: 'test' })).to.match(/[0-9]+(:.*)?/);
        expect(encode({ type: 'message' })).to.match(/[0-9]+(:.*)?/);
      });
    });

    describe('decoding error handing', function () {
      var err = { type: 'error', data: 'parser error' };

      it('should disallow bad format', function () {
        expect(decode(':::')).to.eql(err);
      })

      it('should disallow inexistent types', function () {
        expect(decode('94103')).to.eql(err);
      });
    });
  });

  describe('payloads', function () {
    describe('basic functionality', function () {
      it('should encode payloads as strings', function () {
        expect(encPayload([{ type: 'ping' }, { type: 'post' }])).to.be.a('string');
      });

      it('should decode payloads as arrays', function () {
        expect(decPayload(encPayload(['1:a', '2:b']))).to.be.an('array');
      });
    });

    describe('encoding and decoding', function () {
      it('should encode/decode packets', function () {
        expect(decPayload(encPayload([{ type: 'message', data: 'a' }])))
          .to.eql([{ type: 'message', data: 'a' }]);
      });

      it('should encode/decode empty payloads', function () {
        expect(decPayload(encPayload([]))).to.have.length(0);
      });
    });

    describe('decoding error handling', function () {
      var err = [{ type: 'error', data: 'parser error' }];

      it('should err on bad payload format', function () {
        expect(decPayload('1!')).to.eql(err);
        expect(decPayload('')).to.eql(err);
        expect(decPayload('))')).to.eql(err);
      });

      it('should err on bad payload length', function () {
        expect(decPayload('1:aa')).to.eql(err);
        expect(decPayload('1:')).to.eql(err);
        expect(decPayload('1:a2:b')).to.eql(err);
      });

      it('should err on bad packet format', function () {
        expect(decPayload('3:99:')).to.eql(err);
      });
    });
  });

});
<commit_msg>Made the parser tests a little more realistic.<commit_after>
/**
 * Test dependencies.
 */

var parser = eio.parser

/**
 * Shortcuts
 */

var encode = parser.encodePacket
  , decode = parser.decodePacket
  , encPayload = parser.encodePayload
  , decPayload = parser.decodePayload

/**
 * Tests.
 */

describe('parser', function () {

  describe('packets', function () {
    describe('basic functionality', function () {
      it('should encode packets as strings', function () {
        expect(encode({ type: 'message', data: 'test' })).to.be.a('string');
      });

      it('should decode packets as objects', function () {
        expect(decode(encode({ type: 'message', data: 'test' }))).to.be.an('object');
      });
    });

    describe('encoding and decoding', function () {
      it('should allow no data', function () {
        expect(decode(encode({ type: 'message' })))
          .to.eql({ type: 'message' });
      });

      it('should encode an open packet', function () {
        expect(decode(encode({ type: 'open', data: '{"some":"json"}' })))
          .to.eql({ type: 'open', data: '{"some":"json"}' });
      });

      it('should encode a close packet', function () {
        expect(decode(encode({ type: 'close' })))
          .to.eql({ type: 'close' });
      });

      it('should encode a ping packet', function () {
        expect(decode(encode({ type: 'ping', data: '1' })))
          .to.eql({ type: 'ping', data: '1' });
      });

      it('should encode a pong packet', function () {
        expect(decode(encode({ type: 'pong', data: '1' })))
          .to.eql({ type: 'pong', data: '1' });
      });

      it('should encode a message packet', function () {
        expect(decode(encode({ type: 'message', data: 'aaa' })))
          .to.eql({ type: 'message', data: 'aaa' });
      });

      it('should encode an error packet', function () {
        expect(decode(encode({ type: 'error', data: 'aaa' })))
          .to.eql({ type: 'error', data: 'aaa' });
      });

      it('should encode a noop packet', function () {
        expect(decode(encode({ type: 'noop', data: 'aaa' })))
          .to.eql({ type: 'noop', data: 'aaa' });
      });

      it('should distinguish between empty data and no data', function () {
        var packet = decode(encode({ type: 'message', data: '' }));
        expect(packet.data).to.equal('');

        packet = decode(encode({ type: 'message' }));
        expect(packet.data).to.be(undefined);
      });

      it('should match the encoding format', function () {
        expect(encode({ type: 'message', data: 'test' })).to.match(/[0-9]+(:.*)?/);
        expect(encode({ type: 'message' })).to.match(/[0-9]+(:.*)?/);
      });
    });

    describe('decoding error handing', function () {
      var err = { type: 'error', data: 'parser error' };

      it('should disallow bad format', function () {
        expect(decode(':::')).to.eql(err);
      })

      it('should disallow inexistent types', function () {
        expect(decode('94103')).to.eql(err);
      });
    });
  });

  describe('payloads', function () {
    describe('basic functionality', function () {
      it('should encode payloads as strings', function () {
        expect(encPayload([{ type: 'ping' }, { type: 'post' }])).to.be.a('string');
      });

      it('should decode payloads as arrays', function () {
        expect(decPayload(encPayload(['1:a', '2:b']))).to.be.an('array');
      });
    });

    describe('encoding and decoding', function () {
      it('should encode/decode packets', function () {
        expect(decPayload(encPayload([{ type: 'message', data: 'a' }])))
          .to.eql([{ type: 'message', data: 'a' }]);
      });

      it('should encode/decode empty payloads', function () {
        expect(decPayload(encPayload([]))).to.have.length(0);
      });
    });

    describe('decoding error handling', function () {
      var err = [{ type: 'error', data: 'parser error' }];

      it('should err on bad payload format', function () {
        expect(decPayload('1!')).to.eql(err);
        expect(decPayload('')).to.eql(err);
        expect(decPayload('))')).to.eql(err);
      });

      it('should err on bad payload length', function () {
        expect(decPayload('1:aa')).to.eql(err);
        expect(decPayload('1:')).to.eql(err);
        expect(decPayload('1:a2:b')).to.eql(err);
      });

      it('should err on bad packet format', function () {
        expect(decPayload('3:99:')).to.eql(err);
      });
    });
  });

});
<|endoftext|>


<commit_before>var chai = require('chai');
var es = require('event-stream');
var expect = chai.expect;
var fulltext = require('lacona-util-fulltext');
var lacona = require('..');
var Readable = require('stream').Readable;
var sinon = require('sinon');
var Writable = require('stream').Writable;

chai.use(require('sinon-chai'));

describe('Phrase', function () {
  var parser;
  beforeEach(function() {
    parser = new lacona.Parser();
  });

  it('handles phrases with extension', function (done) {
    var extended = lacona.createPhrase({
      name: 'test/extended',
      describe: function () {
        return lacona.literal({text: 'test a'});
      }
    });

    var extender = lacona.createPhrase({
      name: 'test/extender',
      extends: ['test/extended'],
      describe: function () {
        return lacona.literal({text: 'test b'});
      }
    });

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return extended();
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(4);
      expect(fulltext.suggestion(data[1].data)).to.equal('test b');
      expect(fulltext.suggestion(data[2].data)).to.equal('test a');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [extender];

    es.readArray(['t'])
    .pipe(parser)
    .pipe(es.writeArray(callback));
  });

  it('handles phrases with overriding', function (done) {
    var overridden = lacona.createPhrase({
      name: 'test/overridden',
      describe: function () {
        return lacona.literal({text: 'test a'});
      }
    });

    var overrider = lacona.createPhrase({
      name: 'test/overrider',
      overrides: ['test/overridden'],
      describe: function () {
        return lacona.literal({text: 'test b'});
      }
    });

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return overridden();
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.suggestion(data[1].data)).to.equal('test b');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [overrider];

    es.readArray(['t'])
    .pipe(parser)
    .pipe(es.writeArray(callback));
  });

  it('allows for recursive phrases without creating an infinite loop', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return lacona.sequence({children: [
          lacona.literal({text: 'na '}),
          lacona.choice({children: [
            lacona.literal({text: 'nopeman'}),
            test()
          ]})
        ]});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(4);
      expect(fulltext.match(data[1].data)).to.equal('na ');
      expect(fulltext.suggestion(data[1].data)).to.equal('nopeman');
      expect(fulltext.match(data[2].data)).to.equal('na ');
      expect(fulltext.suggestion(data[2].data)).to.equal('na ');
      done();
    }

    parser.sentences = [test()];
    es.readArray(['na n'])
      .pipe(parser)
      .pipe(es.writeArray(callback));
  });

  it('allows for nested phrases with the same id', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return include1({id: 'test'});
      }
    });
    var include1 = lacona.createPhrase({
      name: 'test/include1',
      describe: function () {
        return include2({id: 'test'});
      }
    });
    var include2 = lacona.createPhrase({
      name: 'test/include2',
      describe: function () {
        return lacona.literal({value: 'val', text: 'disp', id: 'test'});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.suggestion(data[1].data)).to.equal('disp');
      expect(data[1].data.result.test.test.test).to.equal('val');
      done();
    }

    parser.sentences = [test()];
    es.readArray(['d'])
      .pipe(parser)
      .pipe(es.writeArray(callback));
  });

  it('caches calls to describe', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        return lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          start.push('t');
          start.push(null);
        } else {
          expect(describeSpy).to.have.been.calledOnce;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('changing additions clears the describe cache', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        if (!callbackSpy.called) {
          expect(this.config).to.be.undefined;
        } else {
          expect(this.config).to.equal('test');
        }
        return lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          test.additions = {config: 'test'};
          start.push('t');
          start.push(null);
        } else {
          expect(describeSpy).to.have.been.calledTwice;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('allows phrases to have additions (but not passed to onCreate)', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      onCreate: function () {
        expect(this.config).to.be.undefined;
      },
      describe: function () {
        expect(this.config).to.equal('test');
        return lacona.literal({text: 'test'});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.all(data[1].data)).to.equal('test');
      done();
    }

    test.additions = {config: 'test'};

    parser.sentences = [test()];

    es.readArray([''])
      .pipe(parser)
      .pipe(es.writeArray(callback));
  });

  it('allows extensions to keep their additions', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return lacona.literal({text: 'test'});
      }
    });

    var extender = lacona.createPhrase({
      name: 'test/extender',
      extends: 'test/test',
      describe: function () {
        expect(this.config).to.equal('test');
        return lacona.literal({text: 'ext'});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.all(data[1].data)).to.equal('ext');
      done();
    }

    extender.additions = {config: 'test'};

    parser.sentences = [test()];
    parser.extensions = [extender];

    es.readArray(['e'])
      .pipe(parser)
      .pipe(es.writeArray(callback));

  });

  it('throws for phrases without a default-lang schema', function () {
    expect(function() {
      lacona.createPhrase({
        name: 'test/test',
        translations: [{
          langs: ['en-US'],
          describe: function () {
            return lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(lacona.Error);
  });

  it('throws for translations without a lang', function () {
    expect(function() {
      lacona.createPhrase({
        name: 'test/test',
        translations: [{
          describe: function () {
            return lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(lacona.Error);
  });

  it('throws for phrases without a root', function () {
    expect(function() {
      lacona.createPhrase({
        name: 'test/test'
      });
    }).to.throw(lacona.Error);
  });

  it('throws for phrases without a name', function () {
    expect(function() {
      lacona.createPhrase({
        describe: function() {
          return lacona.literal({text: 'test'});
        }
      });
    }).to.throw(lacona.Error);
  });

});
<commit_msg>Improved test coverage<commit_after>var chai = require('chai');
var es = require('event-stream');
var expect = chai.expect;
var fulltext = require('lacona-util-fulltext');
var lacona = require('..');
var Readable = require('stream').Readable;
var sinon = require('sinon');
var Writable = require('stream').Writable;

chai.use(require('sinon-chai'));

describe('Phrase', function () {
  var parser;
  beforeEach(function() {
    parser = new lacona.Parser();
  });

  it('handles phrases with extension', function (done) {
    var extended = lacona.createPhrase({
      name: 'test/extended',
      describe: function () {
        return lacona.literal({text: 'test a'});
      }
    });

    var extender = lacona.createPhrase({
      name: 'test/extender',
      extends: ['test/extended'],
      describe: function () {
        return lacona.literal({text: 'test b'});
      }
    });

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return extended();
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(4);
      expect(fulltext.suggestion(data[1].data)).to.equal('test b');
      expect(fulltext.suggestion(data[2].data)).to.equal('test a');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [extender];

    es.readArray(['t'])
    .pipe(parser)
    .pipe(es.writeArray(callback));
  });

  it('accepts extensions being removed', function (done) {
    var callbackSpy = sinon.spy();

    var extended = lacona.createPhrase({
      name: 'test/extended',
      describe: function () {
        return lacona.literal({text: 'test a'});
      }
    });

    var extender = lacona.createPhrase({
      name: 'test/extender',
      extends: ['test/extended'],
      describe: function () {
        return lacona.literal({text: 'test b'});
      }
    });

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return extended();
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          expect(fulltext.all(obj.data)).to.equal('test b');
        } else if (callbackSpy.calledTwice) {
          expect(fulltext.all(obj.data)).to.equal('test a');
          parser.extensions = [];
          start.push('t');
          start.push(null);
        } else {
          expect(fulltext.all(obj.data)).to.equal('test a');
          done();
        }
      }
    };

    parser.sentences = [test()];
    parser.extensions = [extender];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('handles phrases with overriding', function (done) {
    var overridden = lacona.createPhrase({
      name: 'test/overridden',
      describe: function () {
        return lacona.literal({text: 'test a'});
      }
    });

    var overrider = lacona.createPhrase({
      name: 'test/overrider',
      overrides: ['test/overridden'],
      describe: function () {
        return lacona.literal({text: 'test b'});
      }
    });

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return overridden();
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.suggestion(data[1].data)).to.equal('test b');
      done();
    }

    parser.sentences = [test()];
    parser.extensions = [overrider];

    es.readArray(['t'])
    .pipe(parser)
    .pipe(es.writeArray(callback));
  });

  it('allows for recursive phrases without creating an infinite loop', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return lacona.sequence({children: [
          lacona.literal({text: 'na '}),
          lacona.choice({children: [
            lacona.literal({text: 'nopeman'}),
            test()
          ]})
        ]});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(4);
      expect(fulltext.match(data[1].data)).to.equal('na ');
      expect(fulltext.suggestion(data[1].data)).to.equal('nopeman');
      expect(fulltext.match(data[2].data)).to.equal('na ');
      expect(fulltext.suggestion(data[2].data)).to.equal('na ');
      done();
    }

    parser.sentences = [test()];
    es.readArray(['na n'])
      .pipe(parser)
      .pipe(es.writeArray(callback));
  });

  it('allows for nested phrases with the same id', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return include1({id: 'test'});
      }
    });
    var include1 = lacona.createPhrase({
      name: 'test/include1',
      describe: function () {
        return include2({id: 'test'});
      }
    });
    var include2 = lacona.createPhrase({
      name: 'test/include2',
      describe: function () {
        return lacona.literal({value: 'val', text: 'disp', id: 'test'});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.suggestion(data[1].data)).to.equal('disp');
      expect(data[1].data.result.test.test.test).to.equal('val');
      done();
    }

    parser.sentences = [test()];
    es.readArray(['d'])
      .pipe(parser)
      .pipe(es.writeArray(callback));
  });

  it('caches calls to describe', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        return lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          start.push('t');
          start.push(null);
        } else {
          expect(describeSpy).to.have.been.calledOnce;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('changing additions clears the describe cache', function (done) {
    var callbackSpy = sinon.spy();
    var describeSpy = sinon.spy();

    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        describeSpy();
        if (!callbackSpy.called) {
          expect(this.config).to.be.undefined;
        } else {
          expect(this.config).to.equal('test');
        }
        return lacona.literal({text: 'test'});
      }
    });

    var start = new Readable({objectMode: true});
    var end = new Writable({objectMode: true});
    start._read = function noop() {};
    end.write = function (obj) {
      if (obj.event === 'data') {
        callbackSpy();
        if (callbackSpy.calledOnce) {
          test.additions = {config: 'test'};
          start.push('t');
          start.push(null);
        } else {
          expect(describeSpy).to.have.been.calledTwice;
          done();
        }
      }
    };

    parser.sentences = [test()];

    start.pipe(parser).pipe(end);
    start.push('t');
  });

  it('allows phrases to have additions (but not passed to onCreate)', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      onCreate: function () {
        expect(this.config).to.be.undefined;
      },
      describe: function () {
        expect(this.config).to.equal('test');
        return lacona.literal({text: 'test'});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.all(data[1].data)).to.equal('test');
      done();
    }

    test.additions = {config: 'test'};

    parser.sentences = [test()];

    es.readArray([''])
      .pipe(parser)
      .pipe(es.writeArray(callback));
  });

  it('allows extensions to keep their additions', function (done) {
    var test = lacona.createPhrase({
      name: 'test/test',
      describe: function () {
        return lacona.literal({text: 'test'});
      }
    });

    var extender = lacona.createPhrase({
      name: 'test/extender',
      extends: 'test/test',
      describe: function () {
        expect(this.config).to.equal('test');
        return lacona.literal({text: 'ext'});
      }
    });

    function callback(err, data) {
      expect(data).to.have.length(3);
      expect(fulltext.all(data[1].data)).to.equal('ext');
      done();
    }

    extender.additions = {config: 'test'};

    parser.sentences = [test()];
    parser.extensions = [extender];

    es.readArray(['e'])
      .pipe(parser)
      .pipe(es.writeArray(callback));

  });

  it('throws for phrases without a default-lang schema', function () {
    expect(function() {
      lacona.createPhrase({
        name: 'test/test',
        translations: [{
          langs: ['en-US'],
          describe: function () {
            return lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(lacona.Error);
  });

  it('throws for translations without a lang', function () {
    expect(function() {
      lacona.createPhrase({
        name: 'test/test',
        translations: [{
          describe: function () {
            return lacona.literal({text: 'whatever'});
          }
        }]
      });
    }).to.throw(lacona.Error);
  });

  it('throws for phrases without a root', function () {
    expect(function() {
      lacona.createPhrase({
        name: 'test/test'
      });
    }).to.throw(lacona.Error);
  });

  it('throws for phrases without a name', function () {
    expect(function() {
      lacona.createPhrase({
        describe: function() {
          return lacona.literal({text: 'test'});
        }
      });
    }).to.throw(lacona.Error);
  });

});
<|endoftext|>


<commit_before>
var eternity = require('../'),
    assert = require('assert');

// create puzzle initial position

var puzzle = eternity.createPuzzle();

// match gray pieces

var width = puzzle.getWidth();
var height = puzzle.getHeight();

for (var x = 0; x < width; x++)
    for (var y = 0; y < height; y++) {
        if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
            assert.equal(puzzle.match(x, y, [0, 0, 0, 0]), null);
        else
            assert.ok(puzzle.match(x, y, [0, 0, 0, 0]));
    }

// match four color piece in inner area

for (var x = 2; x < width - 2; x++)
    for (var y = 2; y < height - 2; y++) {
        var results = puzzle.match(x, y, [1, 2, 3, 4]);
        assert.ok(results);
        assert.ok(Array.isArray(results));
        assert.equal(results.length, 4);
    }

// <commit_msg>Match piece on corner<commit_after>
var eternity = require('../'),
    assert = require('assert');

// create puzzle initial position

var puzzle = eternity.createPuzzle();

// match gray pieces

var width = puzzle.getWidth();
var height = puzzle.getHeight();

for (var x = 0; x < width; x++)
    for (var y = 0; y < height; y++) {
        if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
            assert.equal(puzzle.match(x, y, [0, 0, 0, 0]), null);
        else
            assert.ok(puzzle.match(x, y, [0, 0, 0, 0]));
    }

// match four color piece in inner area

for (var x = 2; x < width - 2; x++)
    for (var y = 2; y < height - 2; y++) {
        var results = puzzle.match(x, y, [1, 2, 3, 4]);
        assert.ok(results);
        assert.ok(Array.isArray(results));
        assert.equal(results.length, 4);
    }

// match piece on corner

var result = puzzle.match(1, 1, [1, 2, 0, 0]);
assert.ok(result);
assert.ok(Array.isArray(result));
assert.equal(result.length, 1);
assert.equal(result[0][0], 0);
assert.equal(result[0][1], 0);
assert.equal(result[0][2], 1);
assert.equal(result[0][3], 2);

<|endoftext|>