<commit_before>'use strict';

const Code = require('code');
const Lab = require('lab');
const DataRetrievalRouter = require('../lib/DataRetrievalRouter');

const lab = exports.lab = Lab.script();
const experiment = lab.experiment;
const test = lab.test;

const expect = Code.expect;

/**
 * Rule based access control policy tests, based on username
 **/
experiment('RBAC internal modular information retrieval', () => {

    const dataRetriever = new DataRetrievalRouter();

    test('should register a valid retriever', (done) => {

        const retriever = (source, key, context) => {
            return 'key-' + key;
        };

        dataRetriever.register('test', retriever);

        expect(dataRetriever.get('test:x')).to.equal('key-x');

        done();
    });

    test('should override a valid retriever (single handler)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register('test-override', retriever1);
        dataRetriever.register('test-override', retriever2, {override: true});

        expect(dataRetriever.get('test-override:test', {})).to.equal('test-2');

        done();
    });

    test('should not override a valid retriever (single handler)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register('test-override-error', retriever1);

        expect(dataRetriever.register.bind(dataRetriever, 'test-override-error', retriever2)).to.throw();

        done();
    });

    test('should override a valid retriever (multiple handlers)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register(['test-override-multiple-1', 'test-override-multiple-2', 'test-override-multiple-3'], retriever1);
        dataRetriever.register(['test-override-multiple-2', 'test-override-multiple-4'], retriever2, {override: true}); // test-override-multiple-2 collides

        expect(dataRetriever.get('test-override-multiple-1:test', {})).to.equal('test-1');
        expect(dataRetriever.get('test-override-multiple-2:test', {})).to.equal('test-2');
        expect(dataRetriever.get('test-override-multiple-3:test', {})).to.equal('test-1');
        expect(dataRetriever.get('test-override-multiple-4:test', {})).to.equal('test-2');

        done();
    });

    test('should not override a valid retriever (multiple handlers)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register(['test-override-error-multiple-1', 'test-override-error-multiple-2', 'test-override-error-multiple-3'], retriever1);
        expect(dataRetriever.register.bind(dataRetriever, ['test-override-error-multiple-2', 'test-override-error-multiple-4'], retriever2)).to.throw(Error, 'There is a data retriever already registered for the source: test-override-error-multiple-2');

        done();
    });

});
<commit_msg>Fix test to obtain exposed dataretrievalrouter from rbac-core<commit_after>'use strict';

const Code = require('code');
const Lab = require('lab');
const DataRetrievalRouter = require('../').DataRetrievalRouter;

const lab = exports.lab = Lab.script();
const experiment = lab.experiment;
const test = lab.test;

const expect = Code.expect;

/**
 * Rule based access control policy tests, based on username
 **/
experiment('RBAC internal modular information retrieval', () => {

    const dataRetriever = new DataRetrievalRouter();

    test('should register a valid retriever', (done) => {

        const retriever = (source, key, context) => {
            return 'key-' + key;
        };

        dataRetriever.register('test', retriever);

        expect(dataRetriever.get('test:x')).to.equal('key-x');

        done();
    });

    test('should override a valid retriever (single handler)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register('test-override', retriever1);
        dataRetriever.register('test-override', retriever2, {override: true});

        expect(dataRetriever.get('test-override:test', {})).to.equal('test-2');

        done();
    });

    test('should not override a valid retriever (single handler)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register('test-override-error', retriever1);

        expect(dataRetriever.register.bind(dataRetriever, 'test-override-error', retriever2)).to.throw();

        done();
    });

    test('should override a valid retriever (multiple handlers)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register(['test-override-multiple-1', 'test-override-multiple-2', 'test-override-multiple-3'], retriever1);
        dataRetriever.register(['test-override-multiple-2', 'test-override-multiple-4'], retriever2, {override: true}); // test-override-multiple-2 collides

        expect(dataRetriever.get('test-override-multiple-1:test', {})).to.equal('test-1');
        expect(dataRetriever.get('test-override-multiple-2:test', {})).to.equal('test-2');
        expect(dataRetriever.get('test-override-multiple-3:test', {})).to.equal('test-1');
        expect(dataRetriever.get('test-override-multiple-4:test', {})).to.equal('test-2');

        done();
    });

    test('should not override a valid retriever (multiple handlers)', (done) => {

        const retriever1 = (source, key, context) => {
            return key + '-1';
        };

        const retriever2 = (source, key, context) => {
            return key + '-2';
        };

        dataRetriever.register(['test-override-error-multiple-1', 'test-override-error-multiple-2', 'test-override-error-multiple-3'], retriever1);
        expect(dataRetriever.register.bind(dataRetriever, ['test-override-error-multiple-2', 'test-override-error-multiple-4'], retriever2)).to.throw(Error, 'There is a data retriever already registered for the source: test-override-error-multiple-2');

        done();
    });

});
<|endoftext|>


<commit_before>
/**
 * Testing dependencies
 */
var mqtt = require('..')
  , abstractClientTests = require("./abstract_client");

/**
 * Modules to be tested
 */
var createClient = require('../lib/mqtt').createSecureClient;

/**
 * Testing options
 */
var port = 9899;

var KEY = __dirname + '/helpers/tls-key.pem';
var CERT = __dirname + '/helpers/tls-cert.pem';

var WRONG_CERT = __dirname + '/helpers/wrong-cert.pem';

/**
 * Test server
 */
var server = mqtt.createSecureServer(KEY, CERT, function (client) {
  client.on('connect', function(packet) {
    if (packet.clientId === 'invalid') {
      client.connack({returnCode: 2});
    } else {
      server.emit('connect', client);
      client.connack({returnCode: 0});
    }
  });

  client.on('publish', function (packet) {
    switch (packet.qos) {
      case 0:
        break;
      case 1:
        client.puback(packet);
        break;
      case 2:
        client.pubrec(packet);
        break;
    }
  });

  client.on('pubrel', function(packet) {
    client.pubcomp(packet);
  });

  client.on('pubrec', function(packet) {
    client.pubrel(packet);
  });

  client.on('pubcomp', function(packet) {
    // Nothing to be done
  });

  client.on('subscribe', function(packet) {
    client.suback({
      messageId: packet.messageId,
      granted: packet.subscriptions.map(function (e) {
        return e.qos;
      })
    });
  });

  client.on('unsubscribe', function(packet) {
    client.unsuback(packet);
  });

  client.on('pingreq', function(packet) {
    client.pingresp();
  });
}).listen(port);

describe('MqttSecureClient', function () {
  abstractClientTests(server, createClient, port);

  describe('with secure parameters', function() {

    it('should validate successfully the CA', function (done) {
      var client = createClient(port, {
        ca: [CERT],
        rejectUnauthorized: true
      });

      client.on('error', done)

      server.once('connect', function(client) {
        done();
      });
    });

    it('should validate unsuccessfully the CA', function (done) {
      var client = createClient(port, {
        ca: [WRONG_CERT],
        rejectUnauthorized: true
      });

      server.once('connect', function(client) {
        done(new Error('it should not happen'));
      });

      client.once('error', function() {
        done()
      })
    });

    it('should emit close on TLS error', function (done) {
      var client = createClient(port, {
        ca: [WRONG_CERT],
        rejectUnauthorized: true
      });

      client.on('error', function() {})

      // TODO node v0.8.x emits multiple close events
      client.once('close', function() {
        done()
      })
    });
  })
});
<commit_msg>Hopefully fixing v0.8.26 on travis.<commit_after>
/**
 * Testing dependencies
 */
var mqtt = require('..')
  , abstractClientTests = require("./abstract_client");

/**
 * Modules to be tested
 */
var createClient = require('../lib/mqtt').createSecureClient;

/**
 * Testing options
 */
var port = 9899;

var KEY = __dirname + '/helpers/tls-key.pem';
var CERT = __dirname + '/helpers/tls-cert.pem';

var WRONG_CERT = __dirname + '/helpers/wrong-cert.pem';

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

/**
 * Test server
 */
var server = mqtt.createSecureServer(KEY, CERT, function (client) {
  client.on('connect', function(packet) {
    if (packet.clientId === 'invalid') {
      client.connack({returnCode: 2});
    } else {
      server.emit('connect', client);
      client.connack({returnCode: 0});
    }
  });

  client.on('publish', function (packet) {
    switch (packet.qos) {
      case 0:
        break;
      case 1:
        client.puback(packet);
        break;
      case 2:
        client.pubrec(packet);
        break;
    }
  });

  client.on('pubrel', function(packet) {
    client.pubcomp(packet);
  });

  client.on('pubrec', function(packet) {
    client.pubrel(packet);
  });

  client.on('pubcomp', function(packet) {
    // Nothing to be done
  });

  client.on('subscribe', function(packet) {
    client.suback({
      messageId: packet.messageId,
      granted: packet.subscriptions.map(function (e) {
        return e.qos;
      })
    });
  });

  client.on('unsubscribe', function(packet) {
    client.unsuback(packet);
  });

  client.on('pingreq', function(packet) {
    client.pingresp();
  });
}).listen(port);

describe('MqttSecureClient', function () {
  abstractClientTests(server, createClient, port);

  describe('with secure parameters', function() {

    it('should validate successfully the CA', function (done) {
      var client = createClient(port, {
        ca: [CERT],
        rejectUnauthorized: true
      });

      client.on('error', done)

      server.once('connect', function(client) {
        done();
      });
    });

    it('should validate unsuccessfully the CA', function (done) {
      var client = createClient(port, {
        ca: [WRONG_CERT],
        rejectUnauthorized: true
      });

      server.once('connect', function(client) {
        done(new Error('it should not happen'));
      });

      client.once('error', function() {
        done()
      })
    });

    it('should emit close on TLS error', function (done) {
      var client = createClient(port, {
        ca: [WRONG_CERT],
        rejectUnauthorized: true
      });

      client.on('error', function() {})

      // TODO node v0.8.x emits multiple close events
      client.once('close', function() {
        done()
      })
    });
  })
});
<|endoftext|>


<commit_before>/*jslint browser: true, forin: true, indent:2, plusplus: true, vars: true */
(function (global, undef) {
  'use strict';

  var util = {

    toString: Object.prototype.toString,

    hasOwnProperty: Object.prototype.hasOwnProperty,

    slice: Array.prototype.slice,

    isObject: function (obj) {
      return util.toString.call(obj) === '[object Object]';
    },

    isArray: function (obj) {
      return util.toString.call(obj) === '[object Array]';
    },

    isFunction: function (obj) {
      return util.toString.call(obj) === '[object Function]';
    },

    isString: function (obj) {
      return util.toString.call(obj) === '[object String]';
    },

    trim: function (s) {
      if (!util.isString(s)) {
        throw new Error('"' + s + '" is not string.');
      }
      return s.replace(/^¥s*|¥s*$/g, '');
    },

    extend: function (obj) {
      var args = util.slice.call(arguments, 1);
      var len = args.length;
      var i;
      var source;
      var prop;
      if (obj === null || obj === undef) {
        return obj;
      }
      for (i = 0; i < len; i++) {
        source = args[i];
        if (source !== null && source !== undef) {
          for (prop in source) {
            if (obj[prop] === undef) {
              obj[prop] = source[prop];
            }
          }
        }
      }
      return obj;
    },

    encodeHtml: function (html) {
      html = (html === null || html === undef) ? '' : String(html);
      return html.replace(/[&"'<>]/g, function (s) {
        switch (s) {
        case '&': return '&';
        case '"': return '"';
        case "'": return ''';
        case '<': return '<';
        case '>': return '>';
        default: return s;
        }
      });
    }

  };

  var core = {

    TEMPURA_CONTEXT_MARK: '__tempura__',

    TEMPURA_OPTIONS: '__tempura__options',

    ROOT_CONTEXT: '$root',

    PARENT_CONTEXT: '$parent',

    THIS: '$this',

    options: {},

    includes: function (directive, template) {
      return template.indexOf('{{' + directive) !== -1;
    },

    walk: function (name, context) {
      var path = name.split('.');
      var value = context[path.shift()];
      while (value !== null && value !== undef && path.length > 0) {
        context = value;
        value = context[path.shift()];
      }
      if (util.isFunction(value)) {
        return value.call(context);
      }
      return value;
    },

    find: function (name, obj) {
      var n = util.trim(name);
      return core.walk(n, obj);
    },

    createContext: function (parent, data) {
      var context = data;
      if (!data[core.TEMPURA_CONTEXT_MARK]) {
        if (!parent[core.TEMPURA_CONTEXT_MARK]) {
          throw new Error('illegal parent context.');
        }
        context = {};
        context[core.TEMPURA_CONTEXT_MARK] = true;
        context[core.TEMPURA_OPTIONS] = parent[core.TEMPURA_OPTIONS];
        context[core.ROOT_CONTEXT] = parent[core.ROOT_CONTEXT];
        context[core.PARENT_CONTEXT] = parent;
        context[core.THIS] = data;
        util.extend(context, data);
      }
      return context;
    },

    transformTags: (function () {
      var regex = new RegExp([
        '{{',
        '([#\\^/!{])?(.+?)\\1?', // $1, $2
        '}}+'
      ].join(''), 'g');
      var getValue = function (name, context) {
        var value = core.find(name, context);
        var options = context[core.TEMPURA_OPTIONS];
        if (options === undef) {
          options = core.options;
        }
        if (util.isFunction(value)) {
          value = value.call(context);
        }
        return value === undef ? '' : value;
      };
      return function (template, context) {
        var callback = function (match, directive, name) {
          var value;
          switch (directive) {
          case '#':
            return '{{#' + name + '}}';
          case '^':
            return '{{^' + name + '}}';
          case '/':
            return '{{/' + name + '}}';
          case '!':
            return '';
          case '{':
            return getValue(name, context);
          default:
            value = getValue(name, context);
            return util.encodeHtml(value);
          }
        };
        var lines = template.split('\n');
        var line;
        var i;
        var len = lines.length;
        for (i = 0; i < len; i++) {
          line = lines[i];
          lines[i] = line.replace(regex, callback);
        }
        return lines.join('\n');
      };
    }()),

    transformSection: (function () {
      var regex = new RegExp([
        '^([\\s\\S]*?)',   // $1
        '{{',
        '([#\\^])\\s*(.+)\\s*', // $2, $3
        '}}',
        '\n*([\\s\\S]*?)', // $4
        '{{',
        '\\/\\s*\\3\\s*',
        '}}',
        '\n*([\\s\\S]*)$' // $5
      ].join(''), 'g');
      return function (template, context) {
        if (!core.includes('#', template) && !core.includes('^', template)) {
          return false;
        }
        return template.replace(regex, function (match, before, type, name, content, after) {
          var renderedBefore = before ? core.transformTags(before, context) : '';
          var renderedAfter = after ? core.transform(after, context) : '';
          var value = core.find(name, context);
          var renderedContent = (function () {
            if (type === '#') {
              if (util.isArray(value)) {
                return (function () {
                  var i;
                  var len = value.length;
                  var array = [];
                  for (i = 0; i < len; i++) {
                    array[i] = core.transform(content, core.createContext(context, value[i]));
                  }
                  return array.join('');
                }());
              } else if (util.isObject(value)) {
                return core.transform(content, core.createContext(context, value));
              } else if (value) {
                return core.transform(content, context);
              }
            } else if (type === '^') {
              if ((util.isArray(value) && value.length === 0) || !value) {
                return core.transform(content, context);
              }
            }
            return '';
          }());
          return renderedBefore + renderedContent + renderedAfter;
        });
      };
    }()),

    transform: function (template, context) {
      var html = core.transformSection(template, context);
      if (html === false) {
        html = core.transformTags(template, context);
      }
      return html;
    },

    createInitialContext: function (data, options) {
      var context = {};
      context[core.TEMPURA_CONTEXT_MARK] = true;
      context[core.TEMPURA_OPTIONS] = options;
      context[core.ROOT_CONTEXT] = context;
      context[core.PARENT_CONTEXT] = null;
      context[core.THIS] = data;
      util.extend(context, data);
      return context;
    },

    toHtml: function (template, data, options) {
      var context = core.createInitialContext(data, options);
      return core.transform(template, context);
    },

    prepare: function (template, options) {
      var opts = util.extend({}, options, core.options);
      return function (data) {
        var html = core.toHtml(template, data, opts);
        return html;
      };
    }

  };

  //noinspection JSUnusedGlobalSymbols
  global.tempura = {

    version: '0.0.1',

    setGlobalOptions: function (options) {
      var original = core.options;
      core.options = util.extend({}, options, original);
    },

    getGlobalOptions: function () {
      return core.options;
    },

    prepare: function (template, options) {
      return core.prepare(template, options);
    },

    // internal
    internal: {
      util: util,
      core: core
    }
  };

}(window));<commit_msg>fixed backslash on trim function.<commit_after>/*jslint browser: true, forin: true, indent:2, plusplus: true, vars: true */
(function (global, undef) {
  'use strict';

  var util = {

    toString: Object.prototype.toString,

    hasOwnProperty: Object.prototype.hasOwnProperty,

    slice: Array.prototype.slice,

    isObject: function (obj) {
      return util.toString.call(obj) === '[object Object]';
    },

    isArray: function (obj) {
      return util.toString.call(obj) === '[object Array]';
    },

    isFunction: function (obj) {
      return util.toString.call(obj) === '[object Function]';
    },

    isString: function (obj) {
      return util.toString.call(obj) === '[object String]';
    },

    trim: function (s) {
      if (!util.isString(s)) {
        throw new Error('"' + s + '" is not string.');
      }
      return s.replace(/^\s*|\s*$/g, '');
    },

    extend: function (obj) {
      var args = util.slice.call(arguments, 1);
      var len = args.length;
      var i;
      var source;
      var prop;
      if (obj === null || obj === undef) {
        return obj;
      }
      for (i = 0; i < len; i++) {
        source = args[i];
        if (source !== null && source !== undef) {
          for (prop in source) {
            if (obj[prop] === undef) {
              obj[prop] = source[prop];
            }
          }
        }
      }
      return obj;
    },

    encodeHtml: function (html) {
      html = (html === null || html === undef) ? '' : String(html);
      return html.replace(/[&"'<>]/g, function (s) {
        switch (s) {
        case '&': return '&';
        case '"': return '"';
        case "'": return ''';
        case '<': return '<';
        case '>': return '>';
        default: return s;
        }
      });
    }

  };

  var core = {

    TEMPURA_CONTEXT_MARK: '__tempura__',

    TEMPURA_OPTIONS: '__tempura__options',

    ROOT_CONTEXT: '$root',

    PARENT_CONTEXT: '$parent',

    THIS: '$this',

    options: {},

    includes: function (directive, template) {
      return template.indexOf('{{' + directive) !== -1;
    },

    walk: function (name, context) {
      var path = name.split('.');
      var value = context[path.shift()];
      while (value !== null && value !== undef && path.length > 0) {
        context = value;
        value = context[path.shift()];
      }
      if (util.isFunction(value)) {
        return value.call(context);
      }
      return value;
    },

    find: function (name, obj) {
      var n = util.trim(name);
      return core.walk(n, obj);
    },

    createContext: function (parent, data) {
      var context = data;
      if (!data[core.TEMPURA_CONTEXT_MARK]) {
        if (!parent[core.TEMPURA_CONTEXT_MARK]) {
          throw new Error('illegal parent context.');
        }
        context = {};
        context[core.TEMPURA_CONTEXT_MARK] = true;
        context[core.TEMPURA_OPTIONS] = parent[core.TEMPURA_OPTIONS];
        context[core.ROOT_CONTEXT] = parent[core.ROOT_CONTEXT];
        context[core.PARENT_CONTEXT] = parent;
        context[core.THIS] = data;
        util.extend(context, data);
      }
      return context;
    },

    transformTags: (function () {
      var regex = new RegExp([
        '{{',
        '([#\\^/!{])?(.+?)\\1?', // $1, $2
        '}}+'
      ].join(''), 'g');
      var getValue = function (name, context) {
        var value = core.find(name, context);
        var options = context[core.TEMPURA_OPTIONS];
        if (options === undef) {
          options = core.options;
        }
        if (util.isFunction(value)) {
          value = value.call(context);
        }
        return value === undef ? '' : value;
      };
      return function (template, context) {
        var callback = function (match, directive, name) {
          var value;
          switch (directive) {
          case '#':
            return '{{#' + name + '}}';
          case '^':
            return '{{^' + name + '}}';
          case '/':
            return '{{/' + name + '}}';
          case '!':
            return '';
          case '{':
            return getValue(name, context);
          default:
            value = getValue(name, context);
            return util.encodeHtml(value);
          }
        };
        var lines = template.split('\n');
        var line;
        var i;
        var len = lines.length;
        for (i = 0; i < len; i++) {
          line = lines[i];
          lines[i] = line.replace(regex, callback);
        }
        return lines.join('\n');
      };
    }()),

    transformSection: (function () {
      var regex = new RegExp([
        '^([\\s\\S]*?)',   // $1
        '{{',
        '([#\\^])\\s*(.+)\\s*', // $2, $3
        '}}',
        '\n*([\\s\\S]*?)', // $4
        '{{',
        '\\/\\s*\\3\\s*',
        '}}',
        '\n*([\\s\\S]*)$' // $5
      ].join(''), 'g');
      return function (template, context) {
        if (!core.includes('#', template) && !core.includes('^', template)) {
          return false;
        }
        return template.replace(regex, function (match, before, type, name, content, after) {
          var renderedBefore = before ? core.transformTags(before, context) : '';
          var renderedAfter = after ? core.transform(after, context) : '';
          var value = core.find(name, context);
          var renderedContent = (function () {
            if (type === '#') {
              if (util.isArray(value)) {
                return (function () {
                  var i;
                  var len = value.length;
                  var array = [];
                  for (i = 0; i < len; i++) {
                    array[i] = core.transform(content, core.createContext(context, value[i]));
                  }
                  return array.join('');
                }());
              } else if (util.isObject(value)) {
                return core.transform(content, core.createContext(context, value));
              } else if (value) {
                return core.transform(content, context);
              }
            } else if (type === '^') {
              if ((util.isArray(value) && value.length === 0) || !value) {
                return core.transform(content, context);
              }
            }
            return '';
          }());
          return renderedBefore + renderedContent + renderedAfter;
        });
      };
    }()),

    transform: function (template, context) {
      var html = core.transformSection(template, context);
      if (html === false) {
        html = core.transformTags(template, context);
      }
      return html;
    },

    createInitialContext: function (data, options) {
      var context = {};
      context[core.TEMPURA_CONTEXT_MARK] = true;
      context[core.TEMPURA_OPTIONS] = options;
      context[core.ROOT_CONTEXT] = context;
      context[core.PARENT_CONTEXT] = null;
      context[core.THIS] = data;
      util.extend(context, data);
      return context;
    },

    toHtml: function (template, data, options) {
      var context = core.createInitialContext(data, options);
      return core.transform(template, context);
    },

    prepare: function (template, options) {
      var opts = util.extend({}, options, core.options);
      return function (data) {
        var html = core.toHtml(template, data, opts);
        return html;
      };
    }

  };

  //noinspection JSUnusedGlobalSymbols
  global.tempura = {

    version: '0.0.1',

    setGlobalOptions: function (options) {
      var original = core.options;
      core.options = util.extend({}, options, original);
    },

    getGlobalOptions: function () {
      return core.options;
    },

    prepare: function (template, options) {
      return core.prepare(template, options);
    },

    // internal
    internal: {
      util: util,
      core: core
    }
  };

}(window));<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const buildResponseRelationships = require('./build-response-relationships');

// This transforms the data from the format that it is in the
// database to the one we need for our endpoint.
// This would one day have things like supporting more types from the ORM
// layer. For now it's pretty basic.
module.exports = function(t, definition, version) {
  const attrs = ([]).concat(_.map(definition.attributes, 'name'));
  const meta = ([]).concat(_.map(definition.meta, 'name'));
  const builtInMeta = definition.builtInMetaNames;
  const relationships = buildResponseRelationships(t, definition, version);

  const pickedAttrs = _.pick(t, attrs);
  const pickedMeta = _.pick(t, meta);
  const pickedBuiltInMeta = _.pick(t, builtInMeta);

  const response = {
    id: String(t.id),
    type: definition.plural_form,
  };

  if (_.size(pickedAttrs)) {
    response.attributes = pickedAttrs;
  }
  if (_.size(pickedMeta) || _.size(pickedBuiltInMeta)) {
    response.meta = Object.assign(pickedMeta, pickedBuiltInMeta);
  }
  if (_.size(relationships)) {
    response.relationships = relationships;
  }

  return response;
};
<commit_msg>Simplify format-transaction<commit_after>'use strict';

const _ = require('lodash');
const buildResponseRelationships = require('./build-response-relationships');

// This transforms the data from the format that it is in the
// database to the one we need for our endpoint.
// This would one day have things like supporting more types from the ORM
// layer. For now it's pretty basic.
module.exports = function(t, definition, version) {
  const pickedAttrs = _.pick(t, definition.attributeNames);
  const pickedMeta = _.pick(t, definition.metaNames);
  const pickedBuiltInMeta = _.pick(t, definition.builtInMetaNames);
  const relationships = buildResponseRelationships(t, definition, version);

  const response = {
    id: String(t.id),
    type: definition.plural_form,
  };

  if (_.size(pickedAttrs)) {
    response.attributes = pickedAttrs;
  }
  if (_.size(pickedMeta) || _.size(pickedBuiltInMeta)) {
    response.meta = Object.assign(pickedMeta, pickedBuiltInMeta);
  }
  if (_.size(relationships)) {
    response.relationships = relationships;
  }

  return response;
};
<|endoftext|>


<commit_before>module.exports = function(config) {
    var browsers;

    if (process.env.KARMA_BROWSERS) {
        browsers = process.env.KARMA_BROWSERS.split(',');
    }

    config.set({
        frameworks: ['mocha'],
        browsers: browsers,
        files: [
            require.resolve('es5-shim'),
            require.resolve('html5shiv/dist/html5shiv'),
            'build/test.js'
        ],
        reporters: ['dots']
    });

    if (process.env.CI && process.env.SAUCE_ACCESS_KEY) {
        var customLaunchers = {
            sauceLabsIE11: {
                base: 'SauceLabs',
                browserName: 'internet explorer',
                version: 11
            },
            sauceLabsIE8: {
                base: 'SauceLabs',
                browserName: 'internet explorer',
                version: 8
            }
        };

        config.set({
            browsers: browsers.concat(Object.keys(customLaunchers)),
            reporters: ['dots', 'saucelabs'],
            captureTimeout: 120000,
            sauceLabs: {
                testName: 'Loud'
            },
            customLaunchers: customLaunchers
        });
    }
};
<commit_msg>Test on Android<commit_after>module.exports = function(config) {
    var browsers;

    if (process.env.KARMA_BROWSERS) {
        browsers = process.env.KARMA_BROWSERS.split(',');
    }

    config.set({
        frameworks: ['mocha'],
        browsers: browsers,
        files: [
            require.resolve('es5-shim'),
            require.resolve('html5shiv/dist/html5shiv'),
            'build/test.js'
        ],
        reporters: ['dots']
    });

    if (process.env.CI && process.env.SAUCE_ACCESS_KEY) {
        var customLaunchers = {
            sauceLabsIE11: {
                base: 'SauceLabs',
                browserName: 'Android',
                deviceName: 'Android Emulator',
                version: '5.1'
            },
            sauceLabsIE8: {
                base: 'SauceLabs',
                browserName: 'internet explorer',
                version: 8
            }
        };

        config.set({
            browsers: browsers.concat(Object.keys(customLaunchers)),
            reporters: ['dots', 'saucelabs'],
            captureTimeout: 120000,
            sauceLabs: {
                testName: 'Loud'
            },
            customLaunchers: customLaunchers
        });
    }
};
<|endoftext|>


<commit_before>import { ShredderStorage } from './storage';
import { MockedRequest } from './models/mocked-request';

export class MockedRequests {

  constructor() {
    this.loadFromStorage();
  }

  loadFromStorage() {
    this.mockedRequests = ShredderStorage.dataTree.mockedRequests
      .map((mockedRequest) => new MockedRequest(mockedRequest));

    ShredderStorage.dataTree.mockedRequests = this.mockedRequests;
  }

  addMockedRequest(capturedRequest) {
    this.mockedRequests.push(new MockedRequest(capturedRequest));
  }

}

export default new MockedRequests();
<commit_msg>improve addMockedRequest method - do not add duplicates, persist in storage<commit_after>import { ShredderStorage } from './storage';
import { MockedRequest } from './models/mocked-request';

export class MockedRequests {

  constructor() {
    this.loadFromStorage();
  }

  loadFromStorage() {
    this.mockedRequests = ShredderStorage.dataTree.mockedRequests
      .map((mockedRequest) => new MockedRequest(mockedRequest));

    ShredderStorage.dataTree.mockedRequests = this.mockedRequests;
  }

  addMockedRequest(capturedRequest) {
    const sameRequestHash = this.mockedRequests
      .filter((request) => request.requestHash === capturedRequest.requestHash)
      .length;

    if (sameRequestHash) {
      return;
    }

    this.mockedRequests.push(
      new MockedRequest(capturedRequest.buildMockedRequestData())
    );

    ShredderStorage.persist();
  }

}

export default new MockedRequests();
<|endoftext|>


<commit_before>const path = require('path');
const fs = require('fs');
const glob = require('glob');
const Mustache = require('mustache');

const helpers = require('./helpers');

function documents() {
  const documentsDir = path.join(process.cwd(), 'documents');

  return fs
    .readdirSync(documentsDir)
    .filter(file => fs.statSync(path.join(documentsDir, file)).isDirectory());
}

function getData(document, version, callback) {
  const dataPath = path.join(process.cwd(), 'documents', document, 'versions', `${version}.json`);

  if (fs.existsSync(dataPath)) {
    const data = JSON.parse(fs.readFileSync(dataPath));

    callback(null, data);
  } else {
    callback(null, {});
  }
}

function wkhtmltopdfCommand(host, document, version) {
  let input = [`page ${host}/${document}/${version}.html`];

  const coverPath = path.join(process.cwd(), `documents/${document}/cover.mustache`);

  if (fs.existsSync(coverPath)) {
    input.unshift(`cover ${host}/${document}/${version}/cover.html`);
  }

  input = input.join(' ');

  const output = path.join(process.cwd(), `tmp/output/${document}.pdf`);

  let options = [
    '--page-size Letter',
    '--margin-top 20mm',
    '--margin-right 20mm',
    '--margin-bottom 30mm',
    '--margin-left 20mm',
    '--disable-smart-shrinking',
    '--zoom 3.12',
    '--print-media-type'
  ];

  const headerPath = path.join(process.cwd(), `documents/${document}/header.mustache`);
  const footerPath = path.join(process.cwd(), `documents/${document}/footer.mustache`);

  if (fs.existsSync(headerPath)) {
    options.push(`--header-html http://localhost:3000/${document}/${version}/header.html`);
  }

  if (fs.existsSync(footerPath)) {
    options.push(`--footer-html http://localhost:3000/${document}/${version}/footer.html`);
  }

  options = options.join(' ');

  return `wkhtmltopdf ${options} ${input} ${output}`;
}

function renderTemplate(filePath, view = {}) {
  const template = fs.readFileSync(filePath).toString();
  const partials = {};

  glob.sync(path.join(process.cwd(), 'documents/shared/**/*.mustache')).forEach(partialPath => {
    const key = partialPath
      .replace(path.join(process.cwd(), 'documents/shared/'), '')
      .replace('.mustache', '');

    partials[key] = fs.readFileSync(partialPath).toString();
  });

  console.log(partials);

  view = Object.assign({}, helpers, view);

  return Mustache.render(template, view, partials);
}

function versionsForDocument(document) {
  const versionsDir = path.join(process.cwd(), 'documents', document, 'versions');

  return fs
    .readdirSync(versionsDir)
    .filter(file => fs.statSync(path.join(versionsDir, file)).isFile())
    .map(file => file.replace(/\.json$/, ''));
}

module.exports = { documents, getData, wkhtmltopdfCommand, renderTemplate, versionsForDocument };
<commit_msg>Remove console.log<commit_after>const path = require('path');
const fs = require('fs');
const glob = require('glob');
const Mustache = require('mustache');

const helpers = require('./helpers');

function documents() {
  const documentsDir = path.join(process.cwd(), 'documents');

  return fs
    .readdirSync(documentsDir)
    .filter(file => fs.statSync(path.join(documentsDir, file)).isDirectory());
}

function getData(document, version, callback) {
  const dataPath = path.join(process.cwd(), 'documents', document, 'versions', `${version}.json`);

  if (fs.existsSync(dataPath)) {
    const data = JSON.parse(fs.readFileSync(dataPath));

    callback(null, data);
  } else {
    callback(null, {});
  }
}

function wkhtmltopdfCommand(host, document, version) {
  let input = [`page ${host}/${document}/${version}.html`];

  const coverPath = path.join(process.cwd(), `documents/${document}/cover.mustache`);

  if (fs.existsSync(coverPath)) {
    input.unshift(`cover ${host}/${document}/${version}/cover.html`);
  }

  input = input.join(' ');

  const output = path.join(process.cwd(), `tmp/output/${document}.pdf`);

  let options = [
    '--page-size Letter',
    '--margin-top 20mm',
    '--margin-right 20mm',
    '--margin-bottom 30mm',
    '--margin-left 20mm',
    '--disable-smart-shrinking',
    '--zoom 3.12',
    '--print-media-type'
  ];

  const headerPath = path.join(process.cwd(), `documents/${document}/header.mustache`);
  const footerPath = path.join(process.cwd(), `documents/${document}/footer.mustache`);

  if (fs.existsSync(headerPath)) {
    options.push(`--header-html http://localhost:3000/${document}/${version}/header.html`);
  }

  if (fs.existsSync(footerPath)) {
    options.push(`--footer-html http://localhost:3000/${document}/${version}/footer.html`);
  }

  options = options.join(' ');

  return `wkhtmltopdf ${options} ${input} ${output}`;
}

function renderTemplate(filePath, view = {}) {
  const template = fs.readFileSync(filePath).toString();
  const partials = {};

  glob.sync(path.join(process.cwd(), 'documents/shared/**/*.mustache')).forEach(partialPath => {
    const key = partialPath
      .replace(path.join(process.cwd(), 'documents/shared/'), '')
      .replace('.mustache', '');

    partials[key] = fs.readFileSync(partialPath).toString();
  });

  view = Object.assign({}, helpers, view);

  return Mustache.render(template, view, partials);
}

function versionsForDocument(document) {
  const versionsDir = path.join(process.cwd(), 'documents', document, 'versions');

  return fs
    .readdirSync(versionsDir)
    .filter(file => fs.statSync(path.join(versionsDir, file)).isFile())
    .map(file => file.replace(/\.json$/, ''));
}

module.exports = { documents, getData, wkhtmltopdfCommand, renderTemplate, versionsForDocument };
<|endoftext|>


<commit_before>/*!
 * nodejs ios-xr grpc connection library
 * Copyright(c) 2016 Cisco Systems
 * Apache v2 Licensed
 */

 'use strict';

/**
 * Module Dependencies
 * @private
 */

var grpc = require('grpc');
var ems_grpc = require(__dirname + '/proto/ems_grpc_grpc_pb.js');
var ems_grpc_msgs = require(__dirname + '/proto/ems_grpc_pb.js');

/**
 * Module Exports
 * @public
 */

module.exports = xrGrpc;

/**
 * Module Source
 * @private
 */

/**
 * Constructor for connection library.
 * Need to implement parameter checking.
 * @param {string} address Address of IOS-XR gRPC server.
 * @param {int} port Port of IOS-XR gRPC server.
 * @param {object} rootCert Root SSL certificate. Needs clarification.
 * @param {object} metadata Object in associative array format containing username, password...
 * @param {object} options Object in associative array format containing options.
 */
function xrGrpc(address, port, rootCert, metadata, options) {
	if (!(this instanceof xrGrpc)) return new xrGrpc(address, port, rootCert, metadata, options);
	// Set parameters
	this.params = {};
	this.params.address = address;
	if (!(port = parseInt(port)))
		throw { name: 'BadPort', message: 'Port is not a number.' };
	this.params.port = port;
	this.params.credentials = rootCert ? grpc.credentials.createSsl(rootCert) : grpc.credentials.createInsecure();
	this.params.metadata = metadata ? this.createMetadata(metadata) : {};
	this.params.options = options ? options : {};
	// Create client objects
	this.xrGrpcClient = new ems_grpc.gRPCConfigOperClient(this.getAddress(), this.params.credentials);
	this.xrGrpcCliClient = new ems_grpc.gRPCExecClient(this.getAddress(), this.params.credentials);
}

/**
 * Return the client parameters
 */
xrGrpc.prototype.toString = function xrGrpcToString() {
	return JSON.stringify(this.params);
}

xrGrpc.prototype.getAddress = function() {
	return this.params.address + ':' + this.params.port.toString();
}

/**
 * Change the params metadata values.
 * @param {object} metadata Object in associative array format containing username, password...
 */
xrGrpc.prototype.setMetadata = function(metadata) {
	this.params.metadata = this.createMetadata(metadata);
}

/**
 * Create metadata for gRPC calls.
 * @param {object} metadata Object in associative array format containing username, password...
 */
xrGrpc.prototype.createMetadata = function(metadata) {
	var meta = new grpc.Metadata();
	for (var key in metadata)
		meta.add(key, metadata[key]);
	return meta;
}

xrGrpc.prototype.createConfigArgs = function(reqId, yangJSON) {
	return new ems_grpc_msgs.ConfigArgs([reqId, yangJSON]);
}

xrGrpc.prototype.createConfigGetArgs = function(reqId, yangPathJSON) {
	return new ems_grpc_msgs.ConfigGetArgs([reqId, yangPathJSON]);
}

/**
 * Get the confg for the specfied YANG path.
 * @param {int} reqId Ignore.
 * @param {string} yangPathJSON YANG path to retrieve config from.
 * @param {function} callback Callback to return data to.
 * @return getConfig wuuuut
 */
xrGrpc.prototype.getConfig = function(reqId, yangPathJSON) {
	return this.xrGrpcClient.getConfig(this.createConfigGetArgs(reqId, yangPathJSON), this.params.metadata, this.params.options);
}

xrGrpc.prototype.mergeConfig = function(reqId, yangJSON) {
	return this.xrGrpcClient.getConfig(this.createConfigArgs(reqId, yangJSON), this.params.metadata, this.params.options);
}

xrGrpc.prototype.deleteConfig = function() {

}

xrGrpc.prototype.replaceConfig = function() {

}

xrGrpc.prototype.cliConfig = function() {

}

xrGrpc.prototype.commitReplace = function() {

}

xrGrpc.prototype.commitConfig = function() {

}

xrGrpc.prototype.configDiscardChanges = function() {

}

xrGrpc.prototype.getOper = function() {

}

xrGrpc.prototype.showCmdTextOutput = function() {

}

xrGrpc.prototype.showCmdJSONOutput = function() {

}

<commit_msg>XRCL-17 Implement ems methods<commit_after>/*!
 * nodejs ios-xr 6.0.1 grpc connection library
 * cisco-ie
 * Copyright(c) 2016 Cisco Systems
 * Apache v2 Licensed
 */

 'use strict';

/**
 * Module Dependencies
 * @private
 */

var grpc = require('grpc');
var ems_grpc = require(__dirname + '/proto/ems_grpc_grpc_pb.js');
var ems_grpc_msgs = require(__dirname + '/proto/ems_grpc_pb.js');

/**
 * Module Exports
 * @public
 */

module.exports = xrGrpc;

/**
 * Module Source
 * @private
 */

/**
 * Constructor for connection library.
 * Need to implement parameter checking.
 * @param {string} address Address of IOS-XR gRPC server.
 * @param {int} port Port of IOS-XR gRPC server.
 * @param {object} rootCert Root SSL certificate. Needs clarification.
 * @param {object} metadata Object in associative array format containing username, password...
 * @param {object} options Object in associative array format containing options.
 */
function xrGrpc(address, port, rootCert, metadata, options) {
	if (!(this instanceof xrGrpc)) return new xrGrpc(address, port, rootCert, metadata, options);
	// Set parameters
	this.params = {};
	this.params.address = address;
	if (!(port = parseInt(port)))
		throw { name: 'BadPort', message: 'Port is not a number.' };
	this.params.port = port;
	// Need to figure out how to validate rootCert
	this.params.credentials = rootCert ? grpc.credentials.createSsl(rootCert) : grpc.credentials.createInsecure();
	this.params.metadata = metadata ? this.createMetadata(metadata) : {};
	this.params.options = options ? options : {};
	// Create client objects
	this.xrGrpcClient = new ems_grpc.gRPCConfigOperClient(this.getAddress(), this.params.credentials);
	this.xrGrpcCliClient = new ems_grpc.gRPCExecClient(this.getAddress(), this.params.credentials);
}

/**
 * Utility Functions
 */

/**
 * Stringify collective parameters and clients on toString.
 * @return {Object} Clients and parameters.
 */
xrGrpc.prototype.toString = function xrGrpcToString() {
	var internals = {
		params: this.params,
		client: this.xrGrpcClient,
		cliClient: this.xrGrpcCliClient
	};
	return JSON.stringify(internals);
}

/**
 * Return server network address for client stub communication.
 */
xrGrpc.prototype.getAddress = function() {
	return this.params.address + ':' + this.params.port.toString();
}

/**
 * Change the metadata parameter values.
 * @param {Object} metadata Object in associative array format containing username, password...
 */
xrGrpc.prototype.setMetadata = function(metadata) {
	this.params.metadata = this.createMetadata(metadata);
}

/**
 * Create metadata for gRPC calls.
 * @param {Object} metadata Object in associative array format containing username, password...
 * @return {Object} gRPC Metadata
 */
xrGrpc.prototype.createMetadata = function(metadata) {
	var meta = new grpc.Metadata();
	for (var key in metadata)
		meta.add(key, metadata[key]);
	return meta;
}

/**
 * Message Creation Functions
 * These are for utility, consistency/abstraction in gRPC payload creation.
 */

xrGrpc.prototype.msgs = {};

xrGrpc.prototype.msgs.ConfigArgs = function(reqId, yangJSON) {
	return new ems_grpc_msgs.ConfigArgs([reqId, yangJSON]);
}

xrGrpc.prototype.msgs.ConfigGetArgs = function(reqId, yangPathJSON) {
	return new ems_grpc_msgs.ConfigGetArgs([reqId, yangPathJSON]);
}

xrGrpc.prototype.msgs.CliConfigArgs = function(reqId, cli) {
	return new ems_grpc_msgs.CliConfigArgs([reqId, cli]);
}

xrGrpc.prototype.msgs.CommitReplaceArgs = function(reqId, cli, yangJSON) {
	return new ems_grpc_msgs.CommitReplaceArgs([reqId, cli, yangJSON]);
}

xrGrpc.prototype.msgs.CommitArgs = function(reqId, commitMsg) {
	// This is inverted for some reason.
	return new ems_grpc_msgs.CommitArgs([commitMsg, reqId]);
}

xrGrpc.prototype.msgs.DiscardChangesArgs = function(reqId) {
	return new ems_grpc_msgs.DiscardChangesArgs([reqId]);
}

xrGrpc.prototype.msgs.GetOperArgs = function(reqId, yangPathJSON) {
	return new ems_grpc_msgs.GetOperArgs([reqId, yangPathJSON]);
}

xrGrpc.prototype.msgs.ShowCmdArgs = function(reqId, cli) {
	return new ems_grpc_msgs.ShowCmdArgs([reqId, cli]);
}

/**
 * User Facing Functions
 * What is most intended to be utilized by the user of the library.
 */

/**
 * Retrieves configuration data.
 * @param {int} reqId Ignore.
 * @param {JSON} yangPathJSON Model path in JSON format.
 * @return {Object} Configuration data in JSON format and error string.
 */
xrGrpc.prototype.getConfig = function(reqId, yangPathJSON) {
	return this.xrGrpcClient.getConfig(this.msgs.ConfigGetArgs(reqId, yangPathJSON), this.params.metadata, this.params.options);
}

/**
 * Merges configuration data.
 * @param {int} reqId Ignore.
 * @param {JSON} yangJSON Modeled data in JSON format.
 * @return {Object} Error string.
 */
xrGrpc.prototype.mergeConfig = function(reqId, yangJSON) {
	return this.xrGrpcClient.mergeConfig(this.msgs.ConfigArgs(reqId, yangJSON), this.params.metadata, this.params.options);
}

/**
 * Deletes configuration data.
 * @param {int} reqId Ignore.
 * @param {JSON} yangJSON Modeled data in JSON format.
 * @return {Object} Error string.
 */
xrGrpc.prototype.deleteConfig = function(reqId, yangJSON) {
	return this.xrGrpcClient.deleteConfig(this.msgs.ConfigArgs(reqId, yangJSON), this.params.metadata, this.params.options);
}

/**
 * Replaces configuration data.
 * @param {int} reqId Ignore.
 * @param {JSON} yangJSON Modeled data in JSON format.
 * @return {Object} Error string.
 */
xrGrpc.prototype.replaceConfig = function(reqId, yangJSON) {
	return this.xrGrpcClient.replaceConfig(this.msgs.ConfigArgs(reqId, yangJSON), this.params.metadata, this.params.options);
}

/**
 * Merges configuration data.
 * @param {int} reqId Ignore.
 * @param {string} cli CLI configuration.
 * @return {Object} Error string.
 */
xrGrpc.prototype.cliConfig = function(reqId, cli) {
	return this.xrGrpcClient.cliConfig(this.msgs.CliConfigArgs(reqId, cli), this.params.metadata, this.params.options);
}

/**
 * Requires documentation.
 */
xrGrpc.prototype.commitReplace = function(reqId, cli, yangJSON) {
	return this.xrGrpcClient.commitReplace(this.msgs.CommitReplaceArgs(reqId, cli, yangJSON), this.params.metadata, this.params.options);
}

/**
 * Requires documentation.
 */
xrGrpc.prototype.commitConfig = function(reqId, commitMsg) {
	return this.xrGrpcClient.commitConfig(this.msgs.CommitArgs(reqId, commitMsg), this.params.metadata, this.params.options);
}

/**
 * Requires documentation.
 */
xrGrpc.prototype.configDiscardChanges = function(reqId) {
	return this.xrGrpcClient.configDiscardChanges(this.msgs.DiscardChangesArgs(reqId), this.params.metadata, this.params.options);
}

/**
 * Retrieves operational (state) data.
 * @param {int} reqId Ignore.
 * @param {JSON} yangPathJSON Model path in JSON format.
 * @return {Object} Operational (state) data in JSON format and error string.
 */
xrGrpc.prototype.getOper = function(reqId, yangPathJSON) {
	return this.xrGrpcClient.getOper(this.msgs.GetOperArgs(reqId, yangPathJSON), this.params.metadata, this.params.options);
}

/**
 * Retrieves show-command output.
 * @param {int} reqId Ignore.
 * @param {string} cli CLI show command.
 * @return {Object} CLI output and error string.
 */
xrGrpc.prototype.showCmdTextOutput = function(reqId, cli) {
	return this.xrGrpcCliClient.showCmdTextOutput(this.msgs.ShowCmdArgs(reqId, cli), this.params.metadata, this.params.options);
}

/**
 * Retrieves show-command output.
 * @param {int} reqId Ignore.
 * @param {string} cli CLI show command.
 * @return {Object} CLI output in JSON format and error string.
 */
xrGrpc.prototype.showCmdJSONOutput = function(reqId, cli) {
	return this.xrGrpcCliClient.showCmdJSONOutput(this.msgs.ShowCmdArgs(reqId, cli), this.params.metadata, this.params.options);
}

<|endoftext|>


<commit_before>
/* global it */
/* global describe */
/* global after */
/* global process */
/* global before */
const Iridium = require('iridium');
const Chai = require('chai');
const R = require('ramda');
const expect = Chai.expect;
const Core = Iridium.Core;
const User = require('./models/user');
const Address = require('./models/address');
const seneca = require('seneca')();
const Bluebird = require('bluebird');
const Otomatk = require('../index');
const Senecafy = Otomatk.Senecafy;
var db, UserModel, AddressModel;
var senecaRole = 'user';
var senecafy = new Senecafy(seneca, senecaRole);

seneca.actAsync = Bluebird.promisify(seneca.act);

before((done) => {
  db = new Core(process.env.DB_URI || 'mongodb://localhost/test');
  return db.connect().then(() => {
    UserModel = new Iridium.Model(db, User);
    AddressModel = new Iridium.Model(db, Address);
    senecafy.load([UserModel, AddressModel]);
    done();
  });
});

// Load up with data;
before((done) => {
  var users = [];
  for (var i = 0; i < 100; i++) {
    users.push({
      username: 'test ' + i,
      email: 'test' + i + '@test.com',
      age: i,
      addresses: [{
        city: 'Boston ' + i,
        zipcode: 5000 + i
      }]
    });
  }
  UserModel.collection.insertMany(users, (err, r) => {
    if (err) {
      return done(err);
    }
    done();
  });
});

describe('Senecafy', () => {
  it('should execute list command without any query', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' })
      .then((data) => {
        expect(data).to.have.length.of(100);
        expect(data).to.be.instanceOf(Array);
        done();
      })
      .catch((err) => {
        done(err);
      })
  });

  it('should list users whose age is above 50', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' }, { data: { age: { $gt: 50 } } })
      .then((data) => {
        expect(data).to.have.length.of.at.least(1);
        expect(data).to.be.instanceOf(Array);
        data.forEach((i) => {
          expect(i.age).to.be.above(50);
        });
        done();
      })
      .catch((err) => {
        done(err);
      });
  });

  it('should get user by ID', (done) => {
    var id;
    UserModel.get().then((u) => u.toJSON()).then((data) => {
      id = data._id.toString();
      console.log(id);
      return seneca
        .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'load' }, { id: id });
    }).then((user) => {
      expect(user._id.toString()).to.equal(id);
      expect(user).not.to.be.null;
      expect(user).not.to.be.undefined;
      done();
    });
  });

  it('should get the user details whose age is 50', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'load' }, { data: { age: 50 } })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined;
        done();
      })
      .catch((err) => {
        done(err);
      });
  });

  it('should save a new user', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          username: 'test_user500',
          email: 'test_user500@test.com',
          age: 500,
          addresses: [{
            zipcode: 15125,
            city: 'TestCity'
          }]
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined
        expect(data._id).not.to.be.undefined;
        expect(data.age).to.equal(500);
        done();
      })
      .catch((err) => {
        done(err);
      });
  });

  it('should update an existing user', (done) => {
    var updateId;
    var preUpdateAge;
    var postUpdateAge = 400;
    var postUpdateAddresses = [{
      zipcode: 1254122,
      city: 'new city'
    }]
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          username: 'test_user200',
          email: 'test_user200@test.com',
          age: 200,
          addresses: [{
            zipcode: 15125,
            city: 'TestCity'
          }]
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        updateId = data._id.toString();
        preUpdateAge = data.age;
        if (data.addresses.length) {
          data.addresses.push(postUpdateAddresses[0]);
        } else {
          data.addresses = postUpdateAddresses;
        }
        data.age = postUpdateAge
        return seneca.actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, { id: updateId, data: data });
      })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined
        expect(data._id).not.to.be.undefined;
        expect(data.age).to.equal(postUpdateAge);
        expect(data.age).to.not.equal(preUpdateAge);
        expect(data._id.toString()).to.equal(updateId);
        done();
      });
  });

  it('should add a new address', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: AddressModel.collectionName, cmd: 'save' }, {
        data: {
          zipcode: 111,
          city: 'Boston',
          state: 'Commonwealth'
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined
        expect(data._id).not.to.be.undefined;
        expect(data.city).to.equal('Boston');
        done();
      });
  });

  it('should throw a invalid object error, on trying to save a user data', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' })
      .catch((err) => {
        expect(err).not.to.be.null;
        expect(err).not.to.be.undefined;
        expect(err.reason).not.to.be.undefined;
        expect(err.reason.httpStatusCode).to.equal(400);
        expect(err.reason.message).to.equal(`Invalid ${UserModel.collectionName} object`);
        done();
      });
  });

  it('should throw a validation error, on trying to save an invalid user data', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          email: 'testlol@test.com',
          age: 125
        }
      })
      .catch((err) => {
        expect(err).not.to.be.null;
        expect(err).not.to.be.undefined;
        expect(err.reason).not.to.be.undefined;
        expect(err.reason.httpStatusCode).to.equal(400);
        expect(err.reason.message).to.have.length.of.at.least(1);
        done();
      });
  });

  it('should select age and email fields in find query', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' }, {
        fields: {
          email: 1,
          age: 1
        }
      })
      .then((data) => {
        expect(data).to.be.instanceOf(Array);
        expect(data).to.have.length.of.at.least(1);
        data.forEach((i) => {
          expect(R.pickBy((v, k) => k === 'username', i)).to.deep.equal({});
        });
        done();
      })
  });

  it('should fetch only 10 records', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' }, {
        options: {
          limit: 10
        }
      })
      .then((data) => {
        expect(data).to.be.instanceOf(Array);
        expect(data).to.have.length(10);
        done();
      });
  });

  it('should accept string _id during update', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          username: 'test_user200',
          email: 'test_user200@test.com',
          age: 200
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        if (data && data._id) {
          data._id = data._id.toString();
        }
        data.email = 'testnewuser200@test.com';
        return seneca.actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, { data: data });
      })
      .then((updated) => {
        expect(updated).not.to.be.null;
        expect(updated).not.to.be.undefined;
        expect(updated.email).to.equal('testnewuser200@test.com');
        done();
      })
      .catch(done);
  });

  it('should remove User of a given ID', (done) => {
    UserModel.get().then((u) => u.toJSON()).then((data) => {
      var id = data._id.toString();
      return seneca.actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'remove' }, { id: id });
    }).then((status) => {
      console.log(status);
      expect(status).not.to.be.null;
      expect(status).not.to.be.undefined;
      expect(status.removed).not.to.be.undefined;
      expect(status.removed).to.equal(1);
      done();
    });
  });
});

after((done) => {
  UserModel.collection.drop((err) => {
    if (err) {
      return done(err);
    }
    db.close();
    done();
  });
});<commit_msg>Build fix :notes:<commit_after>
/* global it */
/* global describe */
/* global after */
/* global process */
/* global before */
const Iridium = require('iridium');
const Chai = require('chai');
const R = require('ramda');
const expect = Chai.expect;
const Core = Iridium.Core;
const User = require('./models/user');
const Address = require('./models/address');
const seneca = require('seneca')();
const Bluebird = require('bluebird');
const Otomatk = require('../index');
const Senecafy = Otomatk.Senecafy;
var db, UserModel, AddressModel;
var senecaRole = 'user';
var senecafy = new Senecafy(seneca, senecaRole);

seneca.actAsync = Bluebird.promisify(seneca.act);

before((done) => {
  db = new Core(process.env.DB_URI || 'mongodb://localhost/test');
  return db.connect().then(() => {
    UserModel = new Iridium.Model(db, User);
    AddressModel = new Iridium.Model(db, Address);
    senecafy.load([UserModel, AddressModel]);
    done();
  });
});

// Load up with data;
before((done) => {
  var users = [];
  for (var i = 0; i < 100; i++) {
    users.push({
      username: 'test ' + i,
      email: 'test' + i + '@test.com',
      age: i,
      addresses: [{
        city: 'Boston ' + i,
        zipcode: 5000 + i
      }]
    });
  }
  UserModel.collection.insertMany(users, (err, r) => {
    if (err) {
      return done(err);
    }
    done();
  });
});

describe('Senecafy', () => {
  it('should execute list command without any query', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' })
      .then((data) => {
        expect(data).to.have.length.of(100);
        expect(data).to.be.instanceOf(Array);
        done();
      })
      .catch((err) => {
        done(err);
      })
  });

  it('should list users whose age is above 50', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' }, { data: { age: { $gt: 50 } } })
      .then((data) => {
        expect(data).to.have.length.of.at.least(1);
        expect(data).to.be.instanceOf(Array);
        data.forEach((i) => {
          expect(i.age).to.be.above(50);
        });
        done();
      })
      .catch((err) => {
        done(err);
      });
  });

  it('should get user by ID', (done) => {
    var id;
    UserModel.get().then((u) => u.toJSON()).then((data) => {
      id = data._id.toString();
      console.log(id);
      return seneca
        .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'load' }, { id: id });
    }).then((user) => {
      expect(user._id.toString()).to.equal(id);
      expect(user).not.to.be.null;
      expect(user).not.to.be.undefined;
      done();
    });
  });

  it('should get the user details whose age is 50', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'load' }, { data: { age: 50 } })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined;
        done();
      })
      .catch((err) => {
        done(err);
      });
  });

  it('should save a new user', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          username: 'test_user500',
          email: 'test_user500@test.com',
          age: 500,
          addresses: [{
            zipcode: 15125,
            city: 'TestCity'
          }]
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined
        expect(data._id).not.to.be.undefined;
        expect(data.age).to.equal(500);
        done();
      })
      .catch((err) => {
        done(err);
      });
  });

  it('should update an existing user', (done) => {
    var updateId;
    var preUpdateAge;
    var postUpdateAge = 400;
    var postUpdateAddresses = [{
      zipcode: 1254122,
      city: 'new city'
    }]
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          username: 'test_user200',
          email: 'test_user200@test.com',
          age: 200,
          addresses: [{
            zipcode: 15125,
            city: 'TestCity'
          }]
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        updateId = data._id.toString();
        preUpdateAge = data.age;
        if (data.addresses.length) {
          data.addresses.push(postUpdateAddresses[0]);
        } else {
          data.addresses = postUpdateAddresses;
        }
        data.age = postUpdateAge
        return seneca.actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, { id: updateId, data: data });
      })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined
        expect(data._id).not.to.be.undefined;
        expect(data.age).to.equal(postUpdateAge);
        expect(data.age).to.not.equal(preUpdateAge);
        expect(data._id.toString()).to.equal(updateId);
        done();
      });
  });

  it('should add a new address', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: AddressModel.collectionName, cmd: 'save' }, {
        data: {
          zipcode: 111,
          city: 'Boston',
          state: 'Commonwealth'
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        expect(data).not.to.be.null;
        expect(data).not.to.be.undefined
        expect(data._id).not.to.be.undefined;
        expect(data.city).to.equal('Boston');
        done();
      });
  });

  it('should throw a invalid object error, on trying to save a user data', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' })
      .catch((err) => {
        expect(err).not.to.be.null;
        expect(err).not.to.be.undefined;
        expect(err.reason).not.to.be.undefined;
        expect(err.reason.httpStatusCode).to.equal(400);
        expect(err.reason.message).to.equal(`Invalid ${UserModel.collectionName} object`);
        done();
      });
  });

  it('should throw a validation error, on trying to save an invalid user data', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          email: 'testlol@test.com',
          age: 125
        }
      })
      .catch((err) => {
        expect(err).not.to.be.null;
        expect(err).not.to.be.undefined;
        expect(err.reason).not.to.be.undefined;
        expect(err.reason.httpStatusCode).to.equal(400);
        expect(err.reason.message).to.have.length.of.at.least(1);
        done();
      });
  });

  it('should select age and email fields in find query', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' }, {
        fields: {
          email: 1,
          age: 1
        }
      })
      .then((data) => {
        expect(data).to.be.instanceOf(Array);
        expect(data).to.have.length.of.at.least(1);
        data.forEach((i) => {
          expect(R.pickBy((v, k) => k === 'username', i)).to.deep.equal({});
        });
        done();
      })
  });

  it('should fetch only 10 records', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'list' }, {
        options: {
          limit: 10
        }
      })
      .then((data) => {
        expect(data).to.be.instanceOf(Array);
        expect(data).to.have.length(10);
        done();
      });
  });

  it('should accept string _id during update', (done) => {
    seneca
      .actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, {
        data: {
          username: 'test_user200',
          email: 'test_user200@test.com',
          age: 200
        },
        options: {
          w: 1
        }
      })
      .then((data) => {
        if (data && data._id) {
          data._id = data._id.toString();
        }
        data.email = 'testnewuser200@test.com';
        return seneca.actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'save' }, { data: data });
      })
      .then((updated) => {
        expect(updated).not.to.be.null;
        expect(updated).not.to.be.undefined;
        expect(updated.email).to.equal('testnewuser200@test.com');
        done();
      })
      .catch(done);
  });

  it('should remove User of a given ID', (done) => {
    UserModel.get().then((u) => u.toJSON()).then((data) => {
      var id = data._id.toString();
      return seneca.actAsync({ role: senecaRole, plugin: UserModel.collectionName, cmd: 'remove' }, { id: id });
    }).then((status) => {
      console.log(status);
      expect(status).not.to.be.null;
      expect(status).not.to.be.undefined;
      expect(status.removed).not.to.be.undefined;
      done();
    });
  });
});

after((done) => {
  UserModel.collection.drop((err) => {
    if (err) {
      return done(err);
    }
    db.close();
    done();
  });
});<|endoftext|>


<commit_before>// Generated automatically by nearley.
module.exports = function () {
    var nearley = (function () {
        var module = {exports: {}};
        (function (module) {
            function Rule(name, symbols, postprocess) {

                return { name: name, symbols: symbols, postprocess: postprocess };

            }

            function State(rule, expect, reference) {

                this.rule = rule;

                this.expect = expect;

                this.reference = reference;

                this.data = [];

            }

            State.prototype.toString = function() {

                var predot = this.rule.symbols.slice(0, this.expect).map(stringify).join(' ');

                return ["{", this.rule.name, "→", predot, "●"].concat(this.rule.symbols.slice(this.expect).map(stringify)).concat(["}," + (this.reference || 0)]).filter(id).join(' ');

                function stringify (e) {

                    if (e.literal) {

                        return JSON.stringify(e.literal);

                    } else {

                        return e.toString();

                    }

                }

                function id(e) {

                    return e;

                }

            };

            State.prototype.nextState = function(data) {

                var state = new State(this.rule, this.expect + 1, this.reference);

                state.data = this.data.slice(0);

                state.data.push(data);

                return state;

            };

            State.prototype.consume = function(inp) {

                var rem = typeof inp === 'string' && this.rule.symbols[this.expect] && this.rule.symbols[this.expect].test && this.rule.symbols[this.expect].test(inp);

                if (rem || (this.rule.symbols[this.expect] && this.rule.symbols[this.expect].literal === inp)) {

                    return this.nextState(inp);

                }

                return false;

            };

            State.prototype.consumeRule = function(inp) {

                if (this.rule.symbols[this.expect] === inp) {

                    return this.nextState(inp);

                }

                return false;

            };

            State.prototype.process = function(table, location, rules, addedRules) {

                if (this.expect === this.rule.symbols.length) {

                    // I have completed a rule

                    if (this.rule.postprocess) {

                        this.data = this.rule.postprocess(this.data);

                    }

                    var w = 0;

                    // We need a while here because the empty rule will

                    // modify table[reference]. (when location === reference)

                    var s,x;

                    while (w < table[this.reference].length) {

                        s = table[this.reference][w];

                        x = s.consumeRule(this.rule.name);

                        if (x) {

                            x.data[x.data.length-1] = this.data;

                            table[location].push(x);

                        }

                        w++;

                    }

                } else {

                    // I'm not done, but I can predict something

                    var exp = this.rule.symbols[this.expect];

                    // for each rule

                    var me = this;

                    rules.forEach(function(r) {

                        // if I expect it, and it hasn't been added already

                        if (r.name === exp && addedRules.indexOf(r) === -1) {

                            // Make a note that you've

                            // added it already, and

                            // don't need to add it again; otherwise

                            // left recursive rules are going to

                            // go into an infinite loop

                            // by adding themselves over and

                            // over again.

                            // If it's the null rule, however,

                            // you don't do this because it

                            // affects the current table row,

                            // so you might need it to be

                            // called again later.

                            // Instead, I just insert a copy whose

                            // state has been advanced one position

                            // (since that's all the null rule means

                            // anyway)

                            if (r.symbols.length > 0) {

                                addedRules.push(r);

                                table[location].push(new State(r, 0, location));

                            } else {

                                // Empty rule

                                // This is special

                                var copy = me.consumeRule(r.name);

                                if (r.postprocess) {

                                    copy.data[copy.data.length-1] = r.postprocess([]);

                                } else {

                                    copy.data[copy.data.length-1] = [];

                                }

                                table[location].push(copy);

                            }

                        }

                    });

                }

            };

            function advanceTo(n, table, rules, addedRules) {

                // Advance a table

                var w = 0, s;

                while (w < table[n].length) {

                    s = table[n][w];

                    s.process(table, n, rules, addedRules);

                    w++;

                }

            }

            function setup(table, rules, addedRules, start) {

                // Setup a table

                table.push([]);

                // I could be expecting anything.

                rules.forEach(function (r) {

                    if (r.name === start) {

                        addedRules.push(r);

                        table[0].push(new State(r, 0, 0));

                    }

                });

                advanceTo(0, table, rules, addedRules);

            }

            function Parser(rules, start) {

                this.table = [];

                var addedRules = [];

                this.rules = rules;

                this.start = start || rules[0];

                setup(this.table, rules, addedRules, this.start);

                this.current = 0;

            }

            Parser.prototype.feed = function(chunk) {

                for (var chunkPos = 0; chunkPos < chunk.length; chunkPos++) {

                    // We add new states to table[current+1]

                    this.table.push([]);

                    // Advance all tokens that expect the symbol

                    // So for each state in the previous row,

                    for (var w = 0; w < this.table[this.current + chunkPos].length; w++) {

                        var s = this.table[this.current + chunkPos][w];

                        // Try to consume the token

                        var x = s.consume(chunk[chunkPos]);

                        if (x) {

                            // And then add it

                            this.table[this.current + chunkPos + 1].push(x);

                        }

                    }

                    // Next, for each of the rules, we either

                    // (a) complete it, and try to see if the

                    //     reference row expected that rule

                    // (b) predict the next nonterminal it expects

                    //     by adding that nonterminal's start state

                    // To prevent duplication, we also keep track

                    // of rules we have already added

                    var addedRules = [];

                    advanceTo(this.current + chunkPos + 1, this.table, this.rules, addedRules);

                    // If needed, throw an error:

                    if (this.table[this.table.length-1].length === 0) {

                        // No states at all! This is not good.

                        var err = new Error(

                            "nearley: No possible parsings (@" + (this.current + chunkPos)

                                + ": '" + chunk[chunkPos] + "')."

                        );

                        err.offset = this.current + chunkPos;

                        throw err;

                    }

                }

                this.current += chunkPos;

                // Incrementally keep track of results

                this.results = this.finish();

                // Allow chaining, for whatever it's worth

                return this;

            };

            Parser.prototype.finish = function() {

                // Return the possible parsings

                var considerations = [];

                var myself = this;

                this.table[this.table.length-1].forEach(function (t) {

                    if (t.rule.name === myself.start && t.expect === t.rule.symbols.length && t.reference === 0) {

                        considerations.push(t);

                    }

                });

                return considerations.map(function(c) {return c.data; });

            };

            module.exports = {

                Parser: Parser,

                rule: Rule

            };

        })(module, module.exports);
        return module.exports;
    })();;
    var id = function id(d) {

        return d[0];

    };

    return new nearley.Parser([ {"name": "final","postprocess":  function(d) { return d[1]; } ,"symbols":[ "whit?", "prog", "whit?" ]}, {"name": "prog","postprocess":  function(d) { return [d[0]]; } ,"symbols":[ "prod" ]}, {"name": "prog","postprocess":  function(d) { return [d[0]].concat(d[2]); } ,"symbols":[ "prod", "whit", "prog" ]}, {"name": "prod","postprocess":  function(d) { return {name: d[0], rules: d[5]}; } ,"symbols":[ "word", "whit?", {"literal":"-"}, {"literal":">"}, "whit?", "expression+" ]}, {"name": "prod","postprocess":  function(d) { return {body: d[2]}; } ,"symbols":[ {"literal":"@"}, "whit?", "js" ]}, {"name": "expression+","symbols":[ "completeexpression" ]}, {"name": "expression+","postprocess":  function(d) { return d[0].concat([d[4]]); } ,"symbols":[ "expression+", "whit?", {"literal":"|"}, "whit?", "completeexpression" ]}, {"name": "completeexpression","postprocess":  function(d) { return {tokens: d[0]}; } ,"symbols":[ "expr" ]}, {"name": "completeexpression","postprocess":  function(d) { return {tokens: d[0], postprocess: d[2]}; } ,"symbols":[ "expr", "whit?", "js" ]}, {"name": "expr","symbols":[ "word" ]}, {"name": "expr","symbols":[ "string" ]}, {"name": "expr","symbols":[ "charclass" ]}, {"name": "expr","postprocess":  function(d){ return d[0].concat([d[2]]); } ,"symbols":[ "expr", "whit", "word" ]}, {"name": "expr","postprocess":  function(d){ return d[0].concat([d[2]]); } ,"symbols":[ "expr", "whit", "string" ]}, {"name": "expr","postprocess":  function(d) { return d[0].concat([d[2]]); } ,"symbols":[ "expr", "whit", "charclass" ]}, {"name": "word","postprocess":  function(d){ return d[0]; } ,"symbols":[ /[\w\?\+]/ ]}, {"name": "word","postprocess":  function(d){ return d[0]+d[1]; } ,"symbols":[ "word", /[\w\?\+]/ ]}, {"name": "string","postprocess":  function(d) { return { literal: d[1].join("") }; } ,"symbols":[ {"literal":"\""}, "charset", {"literal":"\""} ]}, {"name": "charset","symbols":[  ]}, {"name": "charset","postprocess":  function(d) { return d[0].concat([d[1]]); } ,"symbols":[ "charset", "char" ]}, {"name": "char","postprocess":  function(d) { return d[0]; } ,"symbols":[ /[^ \\\\ \"]/ ]}, {"name": "char","postprocess":  function(d) { return JSON.parse("\""+"\\"+d[1]+"\""); } ,"symbols":[ {"literal":"\\"}, /./ ]}, {"name": "charclass","postprocess":  function(d) { return new RegExp("."); } ,"symbols":[ {"literal":"."} ]}, {"name": "charclass","postprocess":  function(d) { return new RegExp("[" + d[1].join('') + "]"); } ,"symbols":[ {"literal":"["}, "charclassmembers", {"literal":"]"} ]}, {"name": "charclassmembers","symbols":[  ]}, {"name": "charclassmembers","postprocess":  function(d) { return d[0].concat([d[1]]); } ,"symbols":[ "charclassmembers", "charclassmember" ]}, {"name": "charclassmember","postprocess":  function(d) { return d[0]; } ,"symbols":[ /[^\\\]]/ ]}, {"name": "charclassmember","postprocess":  function(d) { return d[0] + d[1]; } ,"symbols":[ {"literal":"\\"}, /./ ]}, {"name": "js","postprocess":  function(d) { return d[2]; } ,"symbols":[ {"literal":"{"}, {"literal":"%"}, "jscode", {"literal":"%"}, {"literal":"}"} ]}, {"name": "jscode","postprocess":  function() {return "";} ,"symbols":[  ]}, {"name": "jscode","postprocess":  function(d) {return d[0] + d[1];} ,"symbols":[ "jscode", /[^%]/ ]}, {"name": "whit","symbols":[ "whitraw" ]}, {"name": "whit","symbols":[ "whitraw?", "comment", "whit?" ]}, {"name": "whit?","symbols":[  ]}, {"name": "whit?","symbols":[ "whit" ]}, {"name": "whitraw","symbols":[ /[\s]/ ]}, {"name": "whitraw","symbols":[ "whitraw", /[\s]/ ]}, {"name": "whitraw?","symbols":[  ]}, {"name": "whitraw?","symbols":[ "whitraw" ]}, {"name": "comment","symbols":[ {"literal":"#"}, "commentchars", {"literal":"\n"} ]}, {"name": "commentchars","symbols":[  ]}, {"name": "commentchars","symbols":[ "commentchars", /[^\n]/ ]} ], "final");};
<commit_msg>remove \r from generated grammar<commit_after>// Generated automatically by nearley.
module.exports = function () {
    var nearley = (function () {
        var module = {exports: {}};
        (function (module) {
            function Rule(name, symbols, postprocess) {
                return { name: name, symbols: symbols, postprocess: postprocess };
            }

            function State(rule, expect, reference) {
                this.rule = rule;
                this.expect = expect;
                this.reference = reference;
                this.data = [];
            }

            State.prototype.toString = function() {
                var predot = this.rule.symbols.slice(0, this.expect).map(stringify).join(' ');

                return ["{", this.rule.name, "→", predot, "●"].concat(this.rule.symbols.slice(this.expect).map(stringify)).concat(["}," + (this.reference || 0)]).filter(id).join(' ');

                function stringify (e) {
                    if (e.literal) {
                        return JSON.stringify(e.literal);
                    } else {
                        return e.toString();
                    }
                }

                function id(e) {
                    return e;
                }
            };

            State.prototype.nextState = function(data) {
                var state = new State(this.rule, this.expect + 1, this.reference);
                state.data = this.data.slice(0);
                state.data.push(data);
                return state;
            };

            State.prototype.consume = function(inp) {
                var rem = typeof inp === 'string' && this.rule.symbols[this.expect] && this.rule.symbols[this.expect].test && this.rule.symbols[this.expect].test(inp);
                if (rem || (this.rule.symbols[this.expect] && this.rule.symbols[this.expect].literal === inp)) {
                    return this.nextState(inp);
                }
                return false;
            };

            State.prototype.consumeRule = function(inp) {
                if (this.rule.symbols[this.expect] === inp) {
                    return this.nextState(inp);
                }
                return false;
            };

            State.prototype.process = function(table, location, rules, addedRules) {
                if (this.expect === this.rule.symbols.length) {
                    // I have completed a rule
                    if (this.rule.postprocess) {
                        this.data = this.rule.postprocess(this.data);
                    }
                    var w = 0;
                    // We need a while here because the empty rule will
                    // modify table[reference]. (when location === reference)
                    var s,x;
                    while (w < table[this.reference].length) {
                        s = table[this.reference][w];
                        x = s.consumeRule(this.rule.name);
                        if (x) {
                            x.data[x.data.length-1] = this.data;
                            table[location].push(x);
                        }
                        w++;
                    }
                } else {
                    // I'm not done, but I can predict something
                    var exp = this.rule.symbols[this.expect];

                    // for each rule
                    var me = this;
                    rules.forEach(function(r) {
                        // if I expect it, and it hasn't been added already
                        if (r.name === exp && addedRules.indexOf(r) === -1) {
                            // Make a note that you've
                            // added it already, and
                            // don't need to add it again; otherwise
                            // left recursive rules are going to
                            // go into an infinite loop
                            // by adding themselves over and
                            // over again.

                            // If it's the null rule, however,
                            // you don't do this because it
                            // affects the current table row,
                            // so you might need it to be
                            // called again later.
                            // Instead, I just insert a copy whose
                            // state has been advanced one position
                            // (since that's all the null rule means
                            // anyway)
                            if (r.symbols.length > 0) {
                                addedRules.push(r);
                                table[location].push(new State(r, 0, location));
                            } else {
                                // Empty rule
                                // This is special
                                var copy = me.consumeRule(r.name);
                                if (r.postprocess) {
                                    copy.data[copy.data.length-1] = r.postprocess([]);
                                } else {
                                    copy.data[copy.data.length-1] = [];
                                }
                                table[location].push(copy);
                            }
                        }
                    });
                }
            };

            function advanceTo(n, table, rules, addedRules) {
                // Advance a table
                var w = 0, s;
                while (w < table[n].length) {
                    s = table[n][w];
                    s.process(table, n, rules, addedRules);
                    w++;
                }
            }

            function setup(table, rules, addedRules, start) {
                // Setup a table
                table.push([]);

                // I could be expecting anything.
                rules.forEach(function (r) {
                    if (r.name === start) {
                        addedRules.push(r);
                        table[0].push(new State(r, 0, 0));
                    }
                });

                advanceTo(0, table, rules, addedRules);
            }

            function Parser(rules, start) {
                this.table = [];
                var addedRules = [];
                this.rules = rules;
                this.start = start || rules[0];

                setup(this.table, rules, addedRules, this.start);
                this.current = 0;
            }

            Parser.prototype.feed = function(chunk) {
                for (var chunkPos = 0; chunkPos < chunk.length; chunkPos++) {
                    // We add new states to table[current+1]
                    this.table.push([]);

                    // Advance all tokens that expect the symbol
                    // So for each state in the previous row,

                    for (var w = 0; w < this.table[this.current + chunkPos].length; w++) {
                        var s = this.table[this.current + chunkPos][w];
                        // Try to consume the token
                        var x = s.consume(chunk[chunkPos]);
                        if (x) {
                            // And then add it
                            this.table[this.current + chunkPos + 1].push(x);
                        }
                    }

                    // Next, for each of the rules, we either
                    // (a) complete it, and try to see if the
                    //     reference row expected that rule
                    // (b) predict the next nonterminal it expects
                    //     by adding that nonterminal's start state
                    // To prevent duplication, we also keep track
                    // of rules we have already added
                    var addedRules = [];
                    advanceTo(this.current + chunkPos + 1, this.table, this.rules, addedRules);

                    // If needed, throw an error:
                    if (this.table[this.table.length-1].length === 0) {
                        // No states at all! This is not good.
                        var err = new Error(
                            "nearley: No possible parsings (@" + (this.current + chunkPos)
                                + ": '" + chunk[chunkPos] + "')."
                        );
                        err.offset = this.current + chunkPos;
                        throw err;
                    }
                }

                this.current += chunkPos;
                // Incrementally keep track of results
                this.results = this.finish();

                // Allow chaining, for whatever it's worth
                return this;
            };

            Parser.prototype.finish = function() {
                // Return the possible parsings
                var considerations = [];
                var myself = this;
                this.table[this.table.length-1].forEach(function (t) {
                    if (t.rule.name === myself.start && t.expect === t.rule.symbols.length && t.reference === 0) {
                        considerations.push(t);
                    }
                });
                return considerations.map(function(c) {return c.data; });
            };

            module.exports = {
                Parser: Parser,
                rule: Rule
            };

        })(module, module.exports);
        return module.exports;
    })();;
    var id = function id(d) {

        return d[0];

    };

    return new nearley.Parser([ {"name": "final","postprocess":  function(d) { return d[1]; } ,"symbols":[ "whit?", "prog", "whit?" ]}, {"name": "prog","postprocess":  function(d) { return [d[0]]; } ,"symbols":[ "prod" ]}, {"name": "prog","postprocess":  function(d) { return [d[0]].concat(d[2]); } ,"symbols":[ "prod", "whit", "prog" ]}, {"name": "prod","postprocess":  function(d) { return {name: d[0], rules: d[5]}; } ,"symbols":[ "word", "whit?", {"literal":"-"}, {"literal":">"}, "whit?", "expression+" ]}, {"name": "prod","postprocess":  function(d) { return {body: d[2]}; } ,"symbols":[ {"literal":"@"}, "whit?", "js" ]}, {"name": "expression+","symbols":[ "completeexpression" ]}, {"name": "expression+","postprocess":  function(d) { return d[0].concat([d[4]]); } ,"symbols":[ "expression+", "whit?", {"literal":"|"}, "whit?", "completeexpression" ]}, {"name": "completeexpression","postprocess":  function(d) { return {tokens: d[0]}; } ,"symbols":[ "expr" ]}, {"name": "completeexpression","postprocess":  function(d) { return {tokens: d[0], postprocess: d[2]}; } ,"symbols":[ "expr", "whit?", "js" ]}, {"name": "expr","symbols":[ "word" ]}, {"name": "expr","symbols":[ "string" ]}, {"name": "expr","symbols":[ "charclass" ]}, {"name": "expr","postprocess":  function(d){ return d[0].concat([d[2]]); } ,"symbols":[ "expr", "whit", "word" ]}, {"name": "expr","postprocess":  function(d){ return d[0].concat([d[2]]); } ,"symbols":[ "expr", "whit", "string" ]}, {"name": "expr","postprocess":  function(d) { return d[0].concat([d[2]]); } ,"symbols":[ "expr", "whit", "charclass" ]}, {"name": "word","postprocess":  function(d){ return d[0]; } ,"symbols":[ /[\w\?\+]/ ]}, {"name": "word","postprocess":  function(d){ return d[0]+d[1]; } ,"symbols":[ "word", /[\w\?\+]/ ]}, {"name": "string","postprocess":  function(d) { return { literal: d[1].join("") }; } ,"symbols":[ {"literal":"\""}, "charset", {"literal":"\""} ]}, {"name": "charset","symbols":[  ]}, {"name": "charset","postprocess":  function(d) { return d[0].concat([d[1]]); } ,"symbols":[ "charset", "char" ]}, {"name": "char","postprocess":  function(d) { return d[0]; } ,"symbols":[ /[^ \\\\ \"]/ ]}, {"name": "char","postprocess":  function(d) { return JSON.parse("\""+"\\"+d[1]+"\""); } ,"symbols":[ {"literal":"\\"}, /./ ]}, {"name": "charclass","postprocess":  function(d) { return new RegExp("."); } ,"symbols":[ {"literal":"."} ]}, {"name": "charclass","postprocess":  function(d) { return new RegExp("[" + d[1].join('') + "]"); } ,"symbols":[ {"literal":"["}, "charclassmembers", {"literal":"]"} ]}, {"name": "charclassmembers","symbols":[  ]}, {"name": "charclassmembers","postprocess":  function(d) { return d[0].concat([d[1]]); } ,"symbols":[ "charclassmembers", "charclassmember" ]}, {"name": "charclassmember","postprocess":  function(d) { return d[0]; } ,"symbols":[ /[^\\\]]/ ]}, {"name": "charclassmember","postprocess":  function(d) { return d[0] + d[1]; } ,"symbols":[ {"literal":"\\"}, /./ ]}, {"name": "js","postprocess":  function(d) { return d[2]; } ,"symbols":[ {"literal":"{"}, {"literal":"%"}, "jscode", {"literal":"%"}, {"literal":"}"} ]}, {"name": "jscode","postprocess":  function() {return "";} ,"symbols":[  ]}, {"name": "jscode","postprocess":  function(d) {return d[0] + d[1];} ,"symbols":[ "jscode", /[^%]/ ]}, {"name": "whit","symbols":[ "whitraw" ]}, {"name": "whit","symbols":[ "whitraw?", "comment", "whit?" ]}, {"name": "whit?","symbols":[  ]}, {"name": "whit?","symbols":[ "whit" ]}, {"name": "whitraw","symbols":[ /[\s]/ ]}, {"name": "whitraw","symbols":[ "whitraw", /[\s]/ ]}, {"name": "whitraw?","symbols":[  ]}, {"name": "whitraw?","symbols":[ "whitraw" ]}, {"name": "comment","symbols":[ {"literal":"#"}, "commentchars", {"literal":"\n"} ]}, {"name": "commentchars","symbols":[  ]}, {"name": "commentchars","symbols":[ "commentchars", /[^\n]/ ]} ], "final");};
<|endoftext|>