<commit_before>// Load modules
var Lab = require('lab');
var Code = require('code');
var Hapi = require('hapi');
var Sequelize = require('sequelize');

// Test shortcuts
var lab = exports.lab = Lab.script();
var expect = Code.expect;
var beforeEach = lab.beforeEach;
var describe = lab.describe;
var it = lab.it;

describe('hapi-sequelized', function() {
    // Hapi server for each test
    var server;

    // Options to test
    var options = {};

    // Setup Hapi server to register the plugin
    beforeEach(function(done) {
        server = new Hapi.Server();
        server.connection();
        done();

        options = {
            host: '127.0.0.1',
            database: 'testing',
            user: 'root',
            pass: '',
            port: 3306,
            dialect: 'mysql',
            models: ['test/models/**/*.js', 'test/other-models/**/*.js'],
            sequelize: {
                define: {
                    timestamps: false
                }
            }
        };

    });

    it('should register the plugin',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function(err) {
                // no errors
                expect(err).to.not.exist;

                // instance of Sequelize should be registered
                expect(server.plugins['hapi-sequelized'].db.sequelize).to.be.an.instanceOf(Sequelize);

                done();
            });
        });

    it('should apply all the options passed during register',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var opt = server.plugins['hapi-sequelized'].db.sequelize.options;
                var config = server.plugins['hapi-sequelized'].db.sequelize.config;

                // test all options in documentation
                expect(opt.dialect).to.equal(options.dialect);
                expect(opt.port).to.equal(options.port);
                expect(opt.host).to.equal(options.host);
                expect(config.database).to.equal(options.database);
                expect(config.username).to.equal(options.user);

                done();
            });
        });

    it('should apply application-wide model options',
        function(done) {

            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if the { timestamps: false } was applied to the User model
                expect(models.User.options.timestamps).to.be.false();

                done();
            });
        });

    it('should import all models from the specified models directory',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if the User model was imported
                expect(models.User).to.exist();

                done();
            });
        });

    it('should apply default host, dialect, port',
        function(done) {
            // unset host, dialect, and port
            delete options.host;
            delete options.port;
            delete options.dialect;

            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function(err) {
                var opt = server.plugins['hapi-sequelized'].db.sequelize.options;
                var config = server.plugins['hapi-sequelized'].db.sequelize.config;

                // check if the default options were applied
                expect(err).to.not.exist();
                expect(opt.dialect).to.equal('mysql');
                expect(opt.port).to.equal(3306);
                expect(opt.host).to.equal('localhost');

                done();
            });
        });

    it('should import all models from the models array specified in options, from all directories, and their respective nested directories, and confirm that the models exist',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if all models were imported
                expect(models.User).to.exist();
                expect(models.Product).to.exist();
                expect(models.Category).to.exist();
                expect(models.BlogRoll).to.exist();
                expect(models.Blog).to.exist();
                expect(models.Post).to.exist();

                done();
            });
        });
});<commit_msg>test: Add test for connection URI.<commit_after>// Load modules
var Lab = require('lab');
var Code = require('code');
var Hapi = require('hapi');
var Sequelize = require('sequelize');

// Test shortcuts
var lab = exports.lab = Lab.script();
var expect = Code.expect;
var beforeEach = lab.beforeEach;
var describe = lab.describe;
var it = lab.it;

describe('hapi-sequelized', function() {
    // Hapi server for each test
    var server;

    // Options to test
    var options = {};

    // Setup Hapi server to register the plugin
    beforeEach(function(done) {
        server = new Hapi.Server();
        server.connection();
        done();

        options = {
            host: '127.0.0.1',
            database: 'testing',
            user: 'root',
            pass: '',
            port: 3306,
            dialect: 'mysql',
            models: ['test/models/**/*.js', 'test/other-models/**/*.js'],
            sequelize: {
                define: {
                    timestamps: false
                }
            }
        };

    });

    it('should register the plugin',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function(err) {
                // no errors
                expect(err).to.not.exist;

                // instance of Sequelize should be registered
                expect(server.plugins['hapi-sequelized'].db.sequelize).to.be.an.instanceOf(Sequelize);

                done();
            });
        });

    it('should apply all the options passed during register',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var opt = server.plugins['hapi-sequelized'].db.sequelize.options;
                var config = server.plugins['hapi-sequelized'].db.sequelize.config;

                // test all options in documentation
                expect(opt.dialect).to.equal(options.dialect);
                expect(opt.port).to.equal(options.port);
                expect(opt.host).to.equal(options.host);
                expect(config.database).to.equal(options.database);
                expect(config.username).to.equal(options.user);

                done();
            });
        });

    it('should apply application-wide model options',
        function(done) {

            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if the { timestamps: false } was applied to the User model
                expect(models.User.options.timestamps).to.be.false();

                done();
            });
        });

    it('should import all models from the specified models directory',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if the User model was imported
                expect(models.User).to.exist();

                done();
            });
        });

    it('should apply default host, dialect, port',
        function(done) {
            // unset host, dialect, and port
            delete options.host;
            delete options.port;
            delete options.dialect;

            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function(err) {
                var opt = server.plugins['hapi-sequelized'].db.sequelize.options;
                var config = server.plugins['hapi-sequelized'].db.sequelize.config;

                // check if the default options were applied
                expect(err).to.not.exist();
                expect(opt.dialect).to.equal('mysql');
                expect(opt.port).to.equal(3306);
                expect(opt.host).to.equal('localhost');

                done();
            });
        });

    it('should import all models from the models array specified in options, from all directories, and their respective nested directories, and confirm that the models exist',
        function(done) {
            var register = {
                register: require('..'),
                options: options
            };

            server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if all models were imported
                expect(models.User).to.exist();
                expect(models.Product).to.exist();
                expect(models.Category).to.exist();
                expect(models.BlogRoll).to.exist();
                expect(models.Blog).to.exist();
                expect(models.Post).to.exist();

                done();
            });
        });

    it('should connect to a database using the URI format',
       function(done) {
            options.uri = options.dialect + '://' + options.user + ':' + options.pass + '@' + options.host + ':' + options.port + '/' + options.database
            delete options.host;
            delete options.port;
            delete options.dialect;
            delete options.user;
            delete options.pass;
            delete options.database;

            var register = {
               register: require('..'),
               options: options
            };

           server.register([register], function() {
                var models = server.plugins['hapi-sequelized'].db.sequelize.models;

                // check if all models were imported
                expect(models.User).to.exist();
                expect(models.Product).to.exist();
                expect(models.Category).to.exist();
                expect(models.BlogRoll).to.exist();
                expect(models.Blog).to.exist();
                expect(models.Post).to.exist();

                done();
           });
       });
});
<|endoftext|>


<commit_before>var pull   = require('pull-stream')
var duplex = require('../')
var net    = require('net')

var test = require('tape')
/*
test('simple', function (t) {

  var server = net.createServer(function (stream) {

    stream.pipe(
    duplex(
      pull.map(function (e) {
        return '' + e
      }).pipe(pull.collect(function (err, ary) {
        console.log(ary)
        t.end()
      })),
      pull.infinite()
      .pipe(pull.asyncMap(function (e, cb) {
        process.nextTick(function () {
          cb(null, e.toString() + '\n')
        })
      }))
      .pipe(pull.take(10))
    )).on('end', function () {
      console.log('PULL -- END')
    })
    .pipe(stream).on('end', function () {
      server.close()
    })

  }).listen(0, function () {
    var stream = net.connect(server.address().port)
    stream.write('hello')
    stream.end()
  })
})
*/

test('header', function (t) {
  var a = []

  var server = net.createServer(function (stream) {
    var defer = pull.defer()

    stream.pipe(
      duplex(function (read) {
        read(null, function (err, len) {
          defer.resolve(
            pull.infinite()
            .pipe(pull.take(Number(len)))
            .pipe(pull.map(function (n) {
              a.push(n)
              return n + '\n'
            }))
          )
        })
      }, defer)
      .on('end', function () {
        console.log('PULL -- END')
      })
    )
    .pipe(stream)

  }).listen(0, function () {
    var stream = net.connect(server.address().port)
    stream.write('10')
    var data = ''
    stream.on('data', function (d) {
      console.log('cData', '' + d)
      data += d
    })
    stream.on('end', function () {
      console.log('END !')
      //stream.end()
      //server.close()
      var nums = data.split('\n').map(Number)
      nums.pop()
      t.deepEqual(nums, a)
      t.end()
    })
  })
})

<commit_msg>remember to close the server<commit_after>var pull   = require('pull-stream')
var duplex = require('../')
var net    = require('net')

var test = require('tape')
/*
test('simple', function (t) {

  var server = net.createServer(function (stream) {

    stream.pipe(
    duplex(
      pull.map(function (e) {
        return '' + e
      }).pipe(pull.collect(function (err, ary) {
        console.log(ary)
        t.end()
      })),
      pull.infinite()
      .pipe(pull.asyncMap(function (e, cb) {
        process.nextTick(function () {
          cb(null, e.toString() + '\n')
        })
      }))
      .pipe(pull.take(10))
    )).on('end', function () {
      console.log('PULL -- END')
    })
    .pipe(stream).on('end', function () {
      server.close()
    })

  }).listen(0, function () {
    var stream = net.connect(server.address().port)
    stream.write('hello')
    stream.end()
  })
})
*/

test('header', function (t) {
  var a = []

  var server = net.createServer(function (stream) {
    var defer = pull.defer()

    stream.pipe(
      duplex(function (read) {
        read(null, function (err, len) {
          defer.resolve(
            pull.infinite()
            .pipe(pull.take(Number(len)))
            .pipe(pull.map(function (n) {
              a.push(n)
              return n + '\n'
            }))
          )
        })
      }, defer)
      .on('end', function () {
        console.log('PULL -- END')
      })
    )
    .pipe(stream)

  }).listen(0, function () {
    var stream = net.connect(server.address().port)
    stream.write('10')
    var data = ''
    stream.on('data', function (d) {
      console.log('cData', '' + d)
      data += d
    })
    stream.on('end', function () {
      console.log('END !')
      stream.end()
      server.close()

      var nums = data.split('\n').map(Number)
      nums.pop()
      t.deepEqual(nums, a)
      t.end()
    })
  })
})

<|endoftext|>


<commit_before>var test = require('blue-tape');
var ServicifyServer = require('servicify-server');
var Promise = require('bluebird');
var rpc = require('node-json-rpc');
var uniqid = require('uniqid');

var ServicifyService = require('..');

test('can be created without a server to connect to yet', function (t) {
  var ps = new ServicifyService();
  t.ok(ps instanceof ServicifyService);
  t.end();
});

test('returned service has expected API', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();
    var identity = require('async-identity');

    return ps.offer(identity, {name: 'async-identity', version: '1.0.0'}).then(function (service) {
      t.ok(service.host, 'has host');
      t.ok(service.port, 'has port');
      t.equal(service.load, 0, '0 load');
      t.equal(typeof service.invoke, 'function', 'has invoke function');
      t.deepEqual(service.server, {host: '127.0.0.1', port: 2020}, 'has server location');
      return service.stop();
    }).then(function () {
      return server.stop();
    });
  });
});

test('supports registering a package by name', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();

    return ps.offer('async-identity').then(function (service) {
      t.ok(service.host, 'has host');
      t.ok(service.port, 'has port');
      return service.stop();
    }).then(function () {
      return server.stop();
    });
  });
});

test('supports registering a package by its absolute directory', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();

    return ps.offer(__dirname + '/../node_modules/async-identity').then(function (service) {
      t.ok(service.host);
      t.ok(service.port);
      return service.stop();
    }).then(function () {
      return server.stop();
    });
  });
});

test('rejects registering a package by its relative directory', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();

    return ps.offer('../node_modules/async-identity').catch(function (err) {
      t.ok(err);
      return server.stop();
    });
  });
});

test('exposes function through rpc', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();
    var identity = require('async-identity');

    return ps.offer(identity, {name: 'async-identity', version: '1.0.0'}).then(function (service) {
      var client = new rpc.Client({
        host: service.host,
        port: service.port,
        path: '/porty',
        strict: true
      });

      return callRpc(client, 'invoke', [10]).then(function (result) {
        t.equal(result, 10);
        return service.stop();
      }).then(function () {
        return server.stop();
      });
    });
  });
});

test('invocations affects load between heartbeats', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService({heartbeat: 10});
    var identity = require('async-identity');

    return ps.offer(identity, {name: 'async-identity', version: '1.0.0'}).then(function (service) {
      var client = new rpc.Client({
        host: service.host,
        port: service.port,
        path: '/porty',
        strict: true
      });
      var startLoad = service.load;

      return Promise.all([
        callRpc(client, 'invoke', [1]),
        callRpc(client, 'invoke', [2]),
        callRpc(client, 'invoke', [3])
      ]).then(function (results) {
        return Promise.delay(5);
      }).then(function () {
        t.ok(startLoad < service.load, startLoad + ' load < ' + service.load + ' load');
        return Promise.delay(10);
      }).then(function () {
        t.equal(service.load, 0);
        return service.stop();
      }).then(function () {
        return server.stop();
      });
    });
  });
});

function withServer() {
  var server = new ServicifyServer();
  return server.listen();
}

function callRpc(client, method, params) {
  return Promise.fromNode(function (cb) {
    client.call({
      'jsonrpc': '2.0',
      'method': method,
      'params': params,
      'id': uniqid()
    }, cb);
  }).then(function (res) {
    return res.result;
  });
}<commit_msg>linting<commit_after>var test = require('blue-tape');
var ServicifyServer = require('servicify-server');
var Promise = require('bluebird');
var rpc = require('node-json-rpc');
var uniqid = require('uniqid');

var ServicifyService = require('..');

test('can be created without a server to connect to yet', function (t) {
  var ps = new ServicifyService();
  t.ok(ps instanceof ServicifyService);
  t.end();
});

test('returned service has expected API', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();
    var identity = require('async-identity');

    return ps.offer(identity, {name: 'async-identity', version: '1.0.0'}).then(function (service) {
      t.ok(service.host, 'has host');
      t.ok(service.port, 'has port');
      t.equal(service.load, 0, '0 load');
      t.equal(typeof service.invoke, 'function', 'has invoke function');
      t.deepEqual(service.server, {host: '127.0.0.1', port: 2020}, 'has server location');
      return service.stop();
    }).then(function () {
      return server.stop();
    });
  });
});

test('supports registering a package by name', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();

    return ps.offer('async-identity').then(function (service) {
      t.ok(service.host, 'has host');
      t.ok(service.port, 'has port');
      return service.stop();
    }).then(function () {
      return server.stop();
    });
  });
});

test('supports registering a package by its absolute directory', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();

    return ps.offer(__dirname + '/../node_modules/async-identity').then(function (service) {
      t.ok(service.host);
      t.ok(service.port);
      return service.stop();
    }).then(function () {
      return server.stop();
    });
  });
});

test('rejects registering a package by its relative directory', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();

    return ps.offer('../node_modules/async-identity').catch(function (err) {
      t.ok(err);
      return server.stop();
    });
  });
});

test('exposes function through rpc', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService();
    var identity = require('async-identity');

    return ps.offer(identity, {name: 'async-identity', version: '1.0.0'}).then(function (service) {
      var client = new rpc.Client({
        host: service.host,
        port: service.port,
        path: '/porty',
        strict: true
      });

      return callRpc(client, 'invoke', [10]).then(function (result) {
        t.equal(result, 10);
        return service.stop();
      }).then(function () {
        return server.stop();
      });
    });
  });
});

test('invocations affects load between heartbeats', function (t) {
  return withServer().then(function (server) {
    var ps = new ServicifyService({heartbeat: 10});
    var identity = require('async-identity');

    return ps.offer(identity, {name: 'async-identity', version: '1.0.0'}).then(function (service) {
      var client = new rpc.Client({
        host: service.host,
        port: service.port,
        path: '/porty',
        strict: true
      });
      var startLoad = service.load;

      return Promise.all([
        callRpc(client, 'invoke', [1]),
        callRpc(client, 'invoke', [2]),
        callRpc(client, 'invoke', [3])
      ]).then(function () {
        return Promise.delay(5);
      }).then(function () {
        t.ok(startLoad < service.load, startLoad + ' load < ' + service.load + ' load');
        return Promise.delay(10);
      }).then(function () {
        t.equal(service.load, 0);
        return service.stop();
      }).then(function () {
        return server.stop();
      });
    });
  });
});

function withServer() {
  var server = new ServicifyServer();
  return server.listen();
}

function callRpc(client, method, params) {
  return Promise.fromNode(function (cb) {
    client.call({
      'jsonrpc': '2.0',
      'method': method,
      'params': params,
      'id': uniqid()
    }, cb);
  }).then(function (res) {
    return res.result;
  });
}<|endoftext|>


<commit_before>require('./utils/toSeconds.js');<commit_msg>test index is not needed<commit_after><|endoftext|>


<commit_before>/* global log */

'use strict'

var request = require('request')

var directPost = function (req, res, endpointUrl, query, options) {
  var headers = {
    'Accept': req.headers.accept,
    'Content-Type': 'application/sparql-query'
  }

  options = options || {}
  options.headers = headers
  options.body = query

  request.post(endpointUrl, options).pipe(res)
}

var urlencodedPost = function (req, res, endpointUrl, query, options) {
  var headers = {
    'Accept': req.headers.accept,
    'Content-Type': 'application/x-www-form-urlencoded'
  }

  options = options || {}
  options.headers = headers
  options.form = {query: query}

  request.post(endpointUrl, options).pipe(res)
}

var sparqlProxy = function (options) {
  var reqOptions = {}

  if (options.authentication) {
    reqOptions.auth = {
      user: options.authentication.user,
      pass: options.authentication.password
    }
  }

  return function (req, res, next) {
    var query

    if (req.method === 'GET') {
      query = req.query.query
    } else if (req.method === 'POST') {
      if ('query' in req.body) {
        query = req.body.query
      } else {
        query = req.body
      }
    } else {
      return next()
    }

    log.info({script: __filename}, 'handle SPARQL request for endpoint: ' + options.endpointUrl)
    log.debug({script: __filename}, 'SPARQL query:' + query)

    switch (options.queryOperation) {
      case 'urlencoded':
        return urlencodedPost(req, res, options.endpointUrl, query, reqOptions)

      default:
        return directPost(req, res, options.endpointUrl, query, reqOptions)
    }
  }
}

module.exports = sparqlProxy
<commit_msg>use sparql-http-client in SPARQL proxy and simplified code<commit_after>/* global log */

'use strict'

var clone = require('lodash/clone')
var defaults = require('lodash/defaults')
var SparqlHttpClient = require('sparql-http-client')

SparqlHttpClient.fetch = require('node-fetch')

function authBasicHeader (user, password) {
  return 'Basic ' + new Buffer(user + ':' + password).toString('base64')
}

function sparqlProxy (options) {
  var queryOptions = {}

  if (options.authentication) {
    queryOptions.headers = {
      Authorization: authBasicHeader(options.authentication.user, options.authentication.password)
    }
  }

  var queryOperation = options.queryOperation || 'postQueryDirect'
  var client = new SparqlHttpClient({endpointUrl: options.endpointUrl})

  return function (req, res, next) {
    var query

    if (req.method === 'GET') {
      query = req.query.query
    } else if (req.method === 'POST') {
      query = req.body.query || req.body
    } else {
      return next()
    }

    log.info({script: __filename}, 'handle SPARQL request for endpoint: ' + options.endpointUrl)
    log.debug({script: __filename}, 'SPARQL query:' + query)

    // merge configuration query options with request query options
    var currentQueryOptions = defaults(clone(queryOptions), {accept: req.headers.accept})

    return client[queryOperation](query, currentQueryOptions).then(function (result) {
      result.headers.forEach(function (value, name) {
        res.setHeader(name, value)
      })

      result.body.pipe(res)
    }).catch(next)
  }
}

module.exports = sparqlProxy
<|endoftext|>


<commit_before>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

'use strict';

var util = require('util'),
  path = require('path'),
  JsonRefs = require('json-refs'),
  utils = require('./util/utils'),
  Constants = require('./util/constants'),
  log = require('./util/logging'),
  ErrorCodes = Constants.ErrorCodes;

/*
 * @class
 * Resolves the swagger spec by unifying x-ms-paths, resolving relative file references if any,
 * resolving the allof is present in any model definition and then setting additionalProperties
 * to false if it is not previously set to true or an object in that definition.
 */
class SpecResolver {

  /*
   * @constructor
   * Initializes a new instance of the SpecResolver class.
   *
   * @param {string} specPath the (remote|local) swagger spec path
   *
   * @param {object} specInJson the parsed spec in json format
   *
   * @return {object} An instance of the SpecResolver class.
   */
  constructor(specPath, specInJson) {
    if (specPath === null || specPath === undefined || typeof specPath.valueOf() !== 'string' || !specPath.trim().length) {
      throw new Error('specPath is a required property of type string and it cannot be an empty string.')
    }

    if (specInJson === null || specInJson === undefined || typeof specInJson !== 'object') {
      throw new Error('specInJson is a required property of type object')
    }
    this.specInJson = specInJson;
    this.specPath = specPath;
    this.specDir = path.dirname(this.specPath);
    this.visitedEntities = {};
    this.resolvedAllOfModels = {};
  }

  /*
   * Merges the x-ms-paths object into the paths object in swagger spec. The method assumes that the
   * paths present in "x-ms-paths" and "paths" are unique. Hence it does a simple union.
   */
  unifyXmsPaths() {
    let self = this;
    //unify x-ms-paths into paths
    let xmsPaths = self.specInJson['x-ms-paths'];
    let paths = self.specInJson.paths;
    if (xmsPaths && xmsPaths instanceof Object && Object.keys(xmsPaths).length > 0) {
      for (let property in xmsPaths) {
        paths[property] = xmsPaths[property];
      }
      self.specInJson.paths = utils.mergeObjects(xmsPaths, paths);
    }
    return Promise.resolve(self);
  }

  /*
   * Resolves the swagger spec by unifying x-ms-paths, resolving relative file references if any,
   * resolving the allof is present in any model definition and then setting additionalProperties
   * to false if it is not previously set to true or an object in that definition.
   */
  resolve() {
    let self = this;
    return self.unifyXmsPaths()
      .then(function() { return self.resolveRelativePaths(); })
      .then(function() { return self.resolveAllOfInDefinitions(); })
      .then(function() { return self.deleteReferencesToAllOf(); })
      .then(function() { return self.setAdditionalPropertiesFalse(); })
      .catch(function (err) {
        let e = {
          message: `An Error occurred while resolving relative references and allOf in model definitions in the swagger spec: "${self.specPath}".`,
          code: ErrorCodes.ResolveSpecError,
          innerErrors: [err]
        };
        log.error(err);
        return Promise.reject(e);
      });
  }

  /*
   * Resolves the references to relative paths in the provided object.
   *
   * @param {object} [doc] the json doc that contains relative references. Default: self.specInJson (current swagger spec).
   *
   * @param {string} [docPath] the absolute (local|remote) path of the doc Default: self.specPath (current swagger spec path).
   *
   * @param {string} [filterType] the type of paths to filter. By default the method will resolve 'relative' and 'remote' references.
   * If provided the value should be 'all'. This indicates that 'local' references should also be resolved apart from the default ones.
   *
   * @return {object} doc fully resolved json document
   */
  resolveRelativePaths(doc, docPath, filterType) {
    let self = this;
    let docDir;
    let options = {
      relativeBase: docDir,
      filter: ['relative', 'remote']
    };

    if (!doc) {
      doc = self.specInJson;
    }
    if (!docPath) {
      docPath = self.specPath;
      docDir = self.specDir;
    }
    if (!docDir) {
      docDir = path.dirname(docPath);
    }
    if (filterType === 'all') {
      delete options.filter;
    }

    let allRefsRemoteRelative = JsonRefs.findRefs(doc, options);
    let promiseFactories = Object.keys(allRefsRemoteRelative).map(function (refName) {
      let refDetails = allRefsRemoteRelative[refName];
      return function () { return self.resolveRelativeReference(refName, refDetails, doc, docPath); };
    });
    if (promiseFactories.length) {
      return utils.executePromisesSequentially(promiseFactories);
    } else {
      return Promise.resolve(doc);
    }
  }

  /*
   * Resolves the relative reference in the provided object. If the object to be resolved contains
   * more relative references then this method will call resolveRelativePaths
   *
   * @param {string} refName the reference name/location that has a relative reference
   *
   * @param {object} refDetails the value or the object that the refName points at
   *
   * @param {object} doc the doc in which the refName exists
   *
   * @param {string} docPath the absolute (local|remote) path of the doc
   *
   * @return undefined the modified object
   */
  resolveRelativeReference(refName, refDetails, doc, docPath) {
    if (!refName || (refName && typeof refName.valueOf() !== 'string')) {
      throw new Error('refName cannot be null or undefined and must be of type "string".');
    }

    if (!refDetails || (refDetails && !(refDetails instanceof Object))) {
      throw new Error('refDetails cannot be null or undefined and must be of type "object".');
    }

    if (!doc || (doc && !(doc instanceof Object))) {
      throw new Error('doc cannot be null or undefined and must be of type "object".');
    }

    if (!docPath || (docPath && typeof docPath.valueOf() !== 'string')) {
      throw new Error('docPath cannot be null or undefined and must be of type "string".');
    }

    let self = this;
    let node = refDetails.def;
    let slicedRefName = refName.slice(1);
    let reference = node['$ref'];
    let parsedReference = utils.parseReferenceInSwagger(reference);
    let docDir = path.dirname(docPath);

    if (parsedReference.filePath) {
      //assuming that everything in the spec is relative to it, let us join the spec directory
      //and the file path in reference.
      docPath = utils.joinPath(docDir, parsedReference.filePath);
    }

    return utils.parseJson(docPath).then(function (result) {
      if (!parsedReference.localReference) {
        //Since there is no local reference we will replace the key in the object with the parsed
        //json (relative) file it is refering to.
        utils.setObject(doc, slicedRefName, result);
        return Promise.resolve(doc);
      } else {
        //resolve the local reference.
        //make the reference local to the doc being processed
        node['$ref'] = parsedReference.localReference.value;
        utils.setObject(doc, slicedRefName, node);
        let slicedLocalReferenceValue = parsedReference.localReference.value.slice(1);
        let referencedObj = self.visitedEntities[slicedLocalReferenceValue];
        if (!referencedObj) {
          //We get the definition/parameter from the relative file and then add it (make it local)
          //to the doc (i.e. self.specInJson) being processed.
          referencedObj = utils.getObject(result, slicedLocalReferenceValue);
          utils.setObject(self.specInJson, slicedLocalReferenceValue, referencedObj);
          self.visitedEntities[slicedLocalReferenceValue] = referencedObj;
          return Promise.resolve(self.resolveRelativePaths(referencedObj, docPath, 'all'));
        } else {
          return Promise.resolve(doc);
        }
      }
    });
  }

  /*
   * Resolves the "allOf" array present in swagger model definitions by composing all the properties of the parent model into the child model.
   */
  resolveAllOfInDefinitions() {
    let self = this;
    let spec = self.specInJson;
    let definitions = spec.definitions;
    let modelNames = Object.keys(self.specInJson.definitions);
    modelNames.map(function (modelName) {
      let model = definitions[modelName];
      let modelRef = '/definitions/' + modelName;
      return self.resolveAllOfInModel(model, modelRef);
    });
    return Promise.resolve(self);
  }

  /*
   * Resolves the "allOf" array present in swagger model definitions by composing all the properties of the parent model into the child model.
   */
  resolveAllOfInModel(model, modelRef) {
    let self = this;
    let spec = self.specInJson;
    if (!model || (model && typeof model !== 'object')) {
      throw new Error(`model cannot be null or undefined and must of type "object".`);
    }

    if (!modelRef || (modelRef && typeof modelRef.valueOf() !== 'string')) {
      throw new Error(`model cannot be null or undefined and must of type "string".`);
    }

    if (modelRef.startsWith('#')) modelRef = modelRef.slice(1);

    if (!self.resolvedAllOfModels[modelRef]) {
      if (model && model.allOf) {
        model.allOf.map(function (item) {
          let referencedModel = item;
          let ref = item['$ref'];
          let slicedRef = ref ? ref.slice(1) : undefined;
          if (ref) {
            referencedModel = utils.getObject(spec, slicedRef);
          }
          if (referencedModel.allOf) {
            self.resolveAllOfInModel(referencedModel, slicedRef);
          }
          model = self.mergeParentAllOfInChild(referencedModel, model);
          self.resolvedAllOfModels[slicedRef] = referencedModel;
          return model;
        });
      } else {
        self.resolvedAllOfModels[modelRef] = model;
        return model;
      }
    }
  }

  /*
   * Merges the properties of the parent model into the child model.
   *
   * @param {object} parent object to be merged. Example: "Resource".
   *
   * @param {object} child object to be merged. Example: "Storage".
   *
   * @return {object} returns the merged child oject
   */
  mergeParentAllOfInChild(parent, child) {
    let self = this;
    if (!parent || (parent && typeof parent !== 'object')) {
      throw new Error(`parent must be of type "object".`);
    }
    if (!child || (child && typeof child !== 'object')) {
      throw new Error(`child must be of type "object".`);
    }
    //merge the parent (Resource) model's properties into the properties
    //of the child (StorageAccount) model.
    if (!parent.properties) parent.properties = {};
    if (!child.properties) child.properties = {};
    child.properties = utils.mergeObjects(parent.properties, child.properties);
    //merge the array of required properties
    if (parent.required) {
      if (!child.required) {
        child.required = [];
      }
      child.required = [...new Set([...parent.required, ...child.required])];
    }
    //merge x-ms-azure-resource
    if (parent['x-ms-azure-resource']) {
      child['x-ms-azure-resource'] = parent['x-ms-azure-resource'];
    }
    return child;
  }

  /*
   * Deletes all the references to allOf from all the model definitions in the swagger spec.
   */
  deleteReferencesToAllOf() {
    let self = this;
    let spec = self.specInJson;
    let definitions = spec.definitions;
    let modelNames = Object.keys(definitions);
    modelNames.map(function (modelName) {
      if (definitions[modelName].allOf) {
        delete definitions[modelName].allOf;
      }
    });
    return Promise.resolve(self);
  }

  /*
   * Sets additionalProperties of the given modelNames to false.
   *
   * @param {array} [modelNames] An array of strings that specifies the modelNames to be processed.
   * Default: All the modelnames from the definitions section in the swagger spec.
   *
   * @param {boolean} [force] A boolean value that indicates whether to ignore the additionalProperties
   * set to true or an object and forcefully set it to false. Default: false.
   */
  setAdditionalPropertiesFalse(modelNames, force) {
    let self = this;
    let spec = self.specInJson;
    let definitions = spec.definitions;

    if (!modelNames) {
      modelNames = Object.keys(definitions);
    }
    modelNames.forEach(function iterator(modelName) {
      let model = definitions[modelName];
      if (model) {
        if (force || (!model.additionalProperties && (!(!model.properties || (model.properties && Object.keys(model.properties).length === 0))))) {
          model.additionalProperties = false;
        }
      }
    });
    return Promise.resolve(self);
  }
}

module.exports = SpecResolver;<commit_msg>working version<commit_after>// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

'use strict';

var util = require('util'),
  path = require('path'),
  JsonRefs = require('json-refs'),
  utils = require('./util/utils'),
  Constants = require('./util/constants'),
  log = require('./util/logging'),
  ErrorCodes = Constants.ErrorCodes;

/*
 * @class
 * Resolves the swagger spec by unifying x-ms-paths, resolving relative file references if any,
 * resolving the allof is present in any model definition and then setting additionalProperties
 * to false if it is not previously set to true or an object in that definition.
 */
class SpecResolver {

  /*
   * @constructor
   * Initializes a new instance of the SpecResolver class.
   *
   * @param {string} specPath the (remote|local) swagger spec path
   *
   * @param {object} specInJson the parsed spec in json format
   *
   * @return {object} An instance of the SpecResolver class.
   */
  constructor(specPath, specInJson) {
    if (specPath === null || specPath === undefined || typeof specPath.valueOf() !== 'string' || !specPath.trim().length) {
      throw new Error('specPath is a required property of type string and it cannot be an empty string.')
    }

    if (specInJson === null || specInJson === undefined || typeof specInJson !== 'object') {
      throw new Error('specInJson is a required property of type object')
    }
    this.specInJson = specInJson;
    this.specPath = specPath;
    this.specDir = path.dirname(this.specPath);
    this.visitedEntities = {};
    this.resolvedAllOfModels = {};
  }

  /*
   * Merges the x-ms-paths object into the paths object in swagger spec. The method assumes that the
   * paths present in "x-ms-paths" and "paths" are unique. Hence it does a simple union.
   */
  unifyXmsPaths() {
    let self = this;
    //unify x-ms-paths into paths
    let xmsPaths = self.specInJson['x-ms-paths'];
    let paths = self.specInJson.paths;
    if (xmsPaths && xmsPaths instanceof Object && Object.keys(xmsPaths).length > 0) {
      for (let property in xmsPaths) {
        paths[property] = xmsPaths[property];
      }
      self.specInJson.paths = utils.mergeObjects(xmsPaths, paths);
    }
    return Promise.resolve(self);
  }

  /*
   * Resolves the swagger spec by unifying x-ms-paths, resolving relative file references if any,
   * resolving the allof is present in any model definition and then setting additionalProperties
   * to false if it is not previously set to true or an object in that definition.
   */
  resolve() {
    let self = this;
    return self.unifyXmsPaths()
      .then(function() { return self.resolveRelativePaths(); })
      .then(function() { return self.resolveAllOfInDefinitions(); })
      .then(function() { return self.deleteReferencesToAllOf(); })
      .then(function() { return self.setAdditionalPropertiesFalse(); })
      .catch(function (err) {
        let e = {
          message: `An Error occurred while resolving relative references and allOf in model definitions in the swagger spec: "${self.specPath}".`,
          code: ErrorCodes.ResolveSpecError,
          innerErrors: [err]
        };
        log.error(err);
        return Promise.reject(e);
      });
  }

  /*
   * Resolves the references to relative paths in the provided object.
   *
   * @param {object} [doc] the json doc that contains relative references. Default: self.specInJson (current swagger spec).
   *
   * @param {string} [docPath] the absolute (local|remote) path of the doc Default: self.specPath (current swagger spec path).
   *
   * @param {string} [filterType] the type of paths to filter. By default the method will resolve 'relative' and 'remote' references.
   * If provided the value should be 'all'. This indicates that 'local' references should also be resolved apart from the default ones.
   *
   * @return {object} doc fully resolved json document
   */
  resolveRelativePaths(doc, docPath, filterType) {
    let self = this;
    let docDir;
    let options = {
      relativeBase: docDir,
      filter: ['relative', 'remote']
    };

    if (!doc) {
      doc = self.specInJson;
    }
    if (!docPath) {
      docPath = self.specPath;
      docDir = self.specDir;
    }
    if (!docDir) {
      docDir = path.dirname(docPath);
    }
    if (filterType === 'all') {
      delete options.filter;
    }

    let allRefsRemoteRelative = JsonRefs.findRefs(doc, options);
    let promiseFactories = Object.keys(allRefsRemoteRelative).map(function (refName) {
      let refDetails = allRefsRemoteRelative[refName];
      return function () { return self.resolveRelativeReference(refName, refDetails, doc, docPath); };
    });
    if (promiseFactories.length) {
      return utils.executePromisesSequentially(promiseFactories);
    } else {
      return Promise.resolve(doc);
    }
  }

  /*
   * Resolves the relative reference in the provided object. If the object to be resolved contains
   * more relative references then this method will call resolveRelativePaths
   *
   * @param {string} refName the reference name/location that has a relative reference
   *
   * @param {object} refDetails the value or the object that the refName points at
   *
   * @param {object} doc the doc in which the refName exists
   *
   * @param {string} docPath the absolute (local|remote) path of the doc
   *
   * @return undefined the modified object
   */
  resolveRelativeReference(refName, refDetails, doc, docPath) {
    if (!refName || (refName && typeof refName.valueOf() !== 'string')) {
      throw new Error('refName cannot be null or undefined and must be of type "string".');
    }

    if (!refDetails || (refDetails && !(refDetails instanceof Object))) {
      throw new Error('refDetails cannot be null or undefined and must be of type "object".');
    }

    if (!doc || (doc && !(doc instanceof Object))) {
      throw new Error('doc cannot be null or undefined and must be of type "object".');
    }

    if (!docPath || (docPath && typeof docPath.valueOf() !== 'string')) {
      throw new Error('docPath cannot be null or undefined and must be of type "string".');
    }

    let self = this;
    let node = refDetails.def;
    let slicedRefName = refName.slice(1);
    let reference = node['$ref'];
    let parsedReference = utils.parseReferenceInSwagger(reference);
    let docDir = path.dirname(docPath);

    if (parsedReference.filePath) {
      //assuming that everything in the spec is relative to it, let us join the spec directory
      //and the file path in reference.
      docPath = utils.joinPath(docDir, parsedReference.filePath);
    }

    return utils.parseJson(docPath).then(function (result) {
      if (!parsedReference.localReference) {
        //Since there is no local reference we will replace the key in the object with the parsed
        //json (relative) file it is refering to.
        utils.setObject(doc, slicedRefName, result);
        return Promise.resolve(doc);
      } else {
        //resolve the local reference.
        //make the reference local to the doc being processed
        node['$ref'] = parsedReference.localReference.value;
        utils.setObject(doc, slicedRefName, node);
        let slicedLocalReferenceValue = parsedReference.localReference.value.slice(1);
        let referencedObj = self.visitedEntities[slicedLocalReferenceValue];
        if (!referencedObj) {
          //We get the definition/parameter from the relative file and then add it (make it local)
          //to the doc (i.e. self.specInJson) being processed.
          referencedObj = utils.getObject(result, slicedLocalReferenceValue);
          utils.setObject(self.specInJson, slicedLocalReferenceValue, referencedObj);
          self.visitedEntities[slicedLocalReferenceValue] = referencedObj;
          return self.resolveRelativePaths(referencedObj, docPath, 'all').then(() => {
            if (result && result.definitions) {
              let unresolvedDefinitions = [];
              for (let defName in result.definitions) {
                if (result.definitions[defName].allOf) {
                  let matchFound = result.definitions[defName].allOf.some((item) => {
                    return (item['$ref'] === `#${slicedLocalReferenceValue}` && !self.visitedEntities[`/definitions/${defName}`]);
                  });
                  if (matchFound) {
                    unresolvedDefinitions.push(defName);
                  }
                }
              }
              if (unresolvedDefinitions.length) {
                unresolvedDefinitions.forEach((definitionName) => {
                  let slicedDefinitionRef = `/definitions/${definitionName}`;
                  let definitionObj = result.definitions[definitionName];
                  utils.setObject(self.specInJson, slicedDefinitionRef, definitionObj);
                  self.visitedEntities[slicedDefinitionRef] = definitionObj;
                  return self.resolveRelativePaths(definitionObj, docPath, 'all');
                });
              } else {
                return Promise.resolve();
              }
            } else {
              return Promise.resolve();
            }
          });
        } else {
          return Promise.resolve(doc);
        }
      }
    });
  }

  /*
   * Resolves the "allOf" array present in swagger model definitions by composing all the properties of the parent model into the child model.
   */
  resolveAllOfInDefinitions() {
    let self = this;
    let spec = self.specInJson;
    let definitions = spec.definitions;
    let modelNames = Object.keys(self.specInJson.definitions);
    modelNames.map(function (modelName) {
      let model = definitions[modelName];
      let modelRef = '/definitions/' + modelName;
      return self.resolveAllOfInModel(model, modelRef);
    });
    return Promise.resolve(self);
  }

  /*
   * Resolves the "allOf" array present in swagger model definitions by composing all the properties of the parent model into the child model.
   */
  resolveAllOfInModel(model, modelRef) {
    let self = this;
    let spec = self.specInJson;
    if (!model || (model && typeof model !== 'object')) {
      throw new Error(`model cannot be null or undefined and must of type "object".`);
    }

    if (!modelRef || (modelRef && typeof modelRef.valueOf() !== 'string')) {
      throw new Error(`model cannot be null or undefined and must of type "string".`);
    }

    if (modelRef.startsWith('#')) modelRef = modelRef.slice(1);

    if (!self.resolvedAllOfModels[modelRef]) {
      if (model && model.allOf) {
        model.allOf.map(function (item) {
          let referencedModel = item;
          let ref = item['$ref'];
          let slicedRef = ref ? ref.slice(1) : undefined;
          if (ref) {
            referencedModel = utils.getObject(spec, slicedRef);
          }
          if (referencedModel.allOf) {
            self.resolveAllOfInModel(referencedModel, slicedRef);
          }
          model = self.mergeParentAllOfInChild(referencedModel, model);
          self.resolvedAllOfModels[slicedRef] = referencedModel;
          return model;
        });
      } else {
        self.resolvedAllOfModels[modelRef] = model;
        return model;
      }
    }
  }

  /*
   * Merges the properties of the parent model into the child model.
   *
   * @param {object} parent object to be merged. Example: "Resource".
   *
   * @param {object} child object to be merged. Example: "Storage".
   *
   * @return {object} returns the merged child oject
   */
  mergeParentAllOfInChild(parent, child) {
    let self = this;
    if (!parent || (parent && typeof parent !== 'object')) {
      throw new Error(`parent must be of type "object".`);
    }
    if (!child || (child && typeof child !== 'object')) {
      throw new Error(`child must be of type "object".`);
    }
    //merge the parent (Resource) model's properties into the properties
    //of the child (StorageAccount) model.
    if (!parent.properties) parent.properties = {};
    if (!child.properties) child.properties = {};
    child.properties = utils.mergeObjects(parent.properties, child.properties);
    //merge the array of required properties
    if (parent.required) {
      if (!child.required) {
        child.required = [];
      }
      child.required = [...new Set([...parent.required, ...child.required])];
    }
    //merge x-ms-azure-resource
    if (parent['x-ms-azure-resource']) {
      child['x-ms-azure-resource'] = parent['x-ms-azure-resource'];
    }
    return child;
  }

  /*
   * Deletes all the references to allOf from all the model definitions in the swagger spec.
   */
  deleteReferencesToAllOf() {
    let self = this;
    let spec = self.specInJson;
    let definitions = spec.definitions;
    let modelNames = Object.keys(definitions);
    modelNames.map(function (modelName) {
      if (definitions[modelName].allOf) {
        delete definitions[modelName].allOf;
      }
    });
    return Promise.resolve(self);
  }

  /*
   * Sets additionalProperties of the given modelNames to false.
   *
   * @param {array} [modelNames] An array of strings that specifies the modelNames to be processed.
   * Default: All the modelnames from the definitions section in the swagger spec.
   *
   * @param {boolean} [force] A boolean value that indicates whether to ignore the additionalProperties
   * set to true or an object and forcefully set it to false. Default: false.
   */
  setAdditionalPropertiesFalse(modelNames, force) {
    let self = this;
    let spec = self.specInJson;
    let definitions = spec.definitions;

    if (!modelNames) {
      modelNames = Object.keys(definitions);
    }
    modelNames.forEach(function iterator(modelName) {
      let model = definitions[modelName];
      if (model) {
        if (force || (!model.additionalProperties && (!(!model.properties || (model.properties && Object.keys(model.properties).length === 0))))) {
          model.additionalProperties = false;
        }
      }
    });
    return Promise.resolve(self);
  }
}

module.exports = SpecResolver;<|endoftext|>


<commit_before>//
// Original source from https://github.com/segmentio/pg-escape
//
var assert = require('assert');
var format = require('../lib');

var testDate = new Date(Date.UTC(2012, 11, 14, 13, 6, 43, 152));
var testArray = [ 'abc', 1, true, null, testDate ];
var testObject = { a: 1, b: 2 };

describe('format(fmt, ...)', function() {
    describe('%s', function() {
        it('should format as a simple string', function() {
            format('some %s here', 'thing').should.equal('some thing here');
            format('some %s thing %s', 'long', 'here').should.equal('some long thing here');
        });
    });

    describe('%%', function() {
        it('should format as %', function() {
            format('some %%', 'thing').should.equal('some %');
        });

        it('should not eat args', function() {
            format('just %% a %s', 'test').should.equal('just % a test');
        });
    });

    describe('%I', function() {
        it('should format as an identifier', function() {
            format('some %I', 'foo/bar/baz').should.equal('some "foo/bar/baz"');
        });
    });

    describe('%L', function() {
        it('should format as a literal', function() {
            format('%L', "Tobi's").should.equal("'Tobi''s'");
        });
    });
});

describe('format.string(val)', function() {
    it('should coerce to a string', function() {
        format.string(undefined).should.equal('');
        format.string(null).should.equal('');
        format.string(true).should.equal('t');
        format.string(false).should.equal('f');
        format.string(0).should.equal('0');
        format.string(15).should.equal('15');
        format.string(-15).should.equal('-15');
        format.string(45.13).should.equal('45.13');
        format.string(-45.13).should.equal('-45.13');
        format.string('something').should.equal('something');
        format.string(testArray).should.equal('abc,1,t,2012-12-14 13:06:43.152+00');
        format.string(testDate).should.equal('2012-12-14 13:06:43.152+00');
        format.string(testObject).should.equal('{"a":1,"b":2}');
    });
});

describe('format.ident(val)', function() {
    it('should quote when necessary', function() {
        format.ident('foo').should.equal('foo');
        format.ident('_foo').should.equal('_foo');
        format.ident('_foo_bar$baz').should.equal('_foo_bar$baz');
        format.ident('test.some.stuff').should.equal('"test.some.stuff"');
        format.ident('test."some".stuff').should.equal('"test.""some"".stuff"');
    });

    it('should quote reserved words', function() {
        format.ident('desc').should.equal('"desc"');
        format.ident('join').should.equal('"join"');
        format.ident('cross').should.equal('"cross"');
    });

    it('should quote', function() {
        format.ident(true).should.equal('"t"');
        format.ident(false).should.equal('"f"');
        format.ident(0).should.equal('"0"');
        format.ident(15).should.equal('"15"');
        format.ident(-15).should.equal('"-15"');
        format.ident(45.13).should.equal('"45.13"');
        format.ident(-45.13).should.equal('"-45.13"');
        format.ident(testDate).should.equal('"2012-12-14 13:06:43.152+00"');
    });

    it('should throw when undefined', function (done) {
        try {
            format.ident(undefined);
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be null or undefined');
            done();
        }
    });

    it('should throw when null', function (done) {
        try {
            format.ident(null);
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be null or undefined');
            done();
        }
    });

    it('should throw when array', function (done) {
        try {
            format.ident([]);
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be an array');
            done();
        }
    });

    it('should throw when object', function (done) {
        try {
            format.ident({});
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be an object');
            done();
        }
    });
});

describe('format.literal(val)', function() {
    it('should return NULL for null', function() {
        format.literal(null).should.equal('NULL');
        format.literal(undefined).should.equal('NULL');
    });

    it('should quote', function() {
        format.literal(true).should.equal("'t'");
        format.literal(false).should.equal("'f'");
        format.literal(0).should.equal("'0'");
        format.literal(15).should.equal("'15'");
        format.literal(-15).should.equal("'-15'");
        format.literal(45.13).should.equal("'45.13'");
        format.literal(-45.13).should.equal("'-45.13'");
        format.literal('hello world').should.equal("'hello world'");
        format.literal(testArray).should.equal("'abc','1','t',NULL,'2012-12-14 13:06:43.152+00'");
        format.literal(testDate).should.equal("'2012-12-14 13:06:43.152+00'");
        format.literal(testObject).should.equal("'{\"a\":1,\"b\":2}'");
    });

    it('should format quotes', function() {
        format.literal("O'Reilly").should.equal("'O''Reilly'");
    });

    it('should format backslashes', function() {
        format.literal('\\whoop\\').should.equal("E'\\\\whoop\\\\'");
    });
});<commit_msg>Update tests to match support for identifier arrays.<commit_after>//
// Original source from https://github.com/segmentio/pg-escape
//
var assert = require('assert');
var format = require('../lib');

var testDate = new Date(Date.UTC(2012, 11, 14, 13, 6, 43, 152));
var testArray = [ 'abc', 1, true, null, testDate ];
var testIdentArray = [ 'abc', 'AbC', 1, true, testDate ];
var testObject = { a: 1, b: 2 };

describe('format(fmt, ...)', function() {
    describe('%s', function() {
        it('should format as a simple string', function() {
            format('some %s here', 'thing').should.equal('some thing here');
            format('some %s thing %s', 'long', 'here').should.equal('some long thing here');
        });
    });

    describe('%%', function() {
        it('should format as %', function() {
            format('some %%', 'thing').should.equal('some %');
        });

        it('should not eat args', function() {
            format('just %% a %s', 'test').should.equal('just % a test');
        });
    });

    describe('%I', function() {
        it('should format as an identifier', function() {
            format('some %I', 'foo/bar/baz').should.equal('some "foo/bar/baz"');
        });
    });

    describe('%L', function() {
        it('should format as a literal', function() {
            format('%L', "Tobi's").should.equal("'Tobi''s'");
        });
    });
});

describe('format.string(val)', function() {
    it('should coerce to a string', function() {
        format.string(undefined).should.equal('');
        format.string(null).should.equal('');
        format.string(true).should.equal('t');
        format.string(false).should.equal('f');
        format.string(0).should.equal('0');
        format.string(15).should.equal('15');
        format.string(-15).should.equal('-15');
        format.string(45.13).should.equal('45.13');
        format.string(-45.13).should.equal('-45.13');
        format.string('something').should.equal('something');
        format.string(testArray).should.equal('abc,1,t,2012-12-14 13:06:43.152+00');
        format.string(testDate).should.equal('2012-12-14 13:06:43.152+00');
        format.string(testObject).should.equal('{"a":1,"b":2}');
    });
});

describe('format.ident(val)', function() {
    it('should quote when necessary', function() {
        format.ident('foo').should.equal('foo');
        format.ident('_foo').should.equal('_foo');
        format.ident('_foo_bar$baz').should.equal('_foo_bar$baz');
        format.ident('test.some.stuff').should.equal('"test.some.stuff"');
        format.ident('test."some".stuff').should.equal('"test.""some"".stuff"');
    });

    it('should quote reserved words', function() {
        format.ident('desc').should.equal('"desc"');
        format.ident('join').should.equal('"join"');
        format.ident('cross').should.equal('"cross"');
    });

    it('should quote', function() {
        format.ident(true).should.equal('"t"');
        format.ident(false).should.equal('"f"');
        format.ident(0).should.equal('"0"');
        format.ident(15).should.equal('"15"');
        format.ident(-15).should.equal('"-15"');
        format.ident(45.13).should.equal('"45.13"');
        format.ident(-45.13).should.equal('"-45.13"');
        format.ident(testIdentArray).should.equal('abc,"AbC","1","t","2012-12-14 13:06:43.152+00"');
        format.ident(testDate).should.equal('"2012-12-14 13:06:43.152+00"');
    });

    it('should throw when undefined', function (done) {
        try {
            format.ident(undefined);
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be null or undefined');
            done();
        }
    });

    it('should throw when null', function (done) {
        try {
            format.ident(null);
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be null or undefined');
            done();
        }
    });

    it('should throw when object', function (done) {
        try {
            format.ident({});
        } catch (err) {
            assert(err.message === 'SQL identifier cannot be an object');
            done();
        }
    });
});

describe('format.literal(val)', function() {
    it('should return NULL for null', function() {
        format.literal(null).should.equal('NULL');
        format.literal(undefined).should.equal('NULL');
    });

    it('should quote', function() {
        format.literal(true).should.equal("'t'");
        format.literal(false).should.equal("'f'");
        format.literal(0).should.equal("'0'");
        format.literal(15).should.equal("'15'");
        format.literal(-15).should.equal("'-15'");
        format.literal(45.13).should.equal("'45.13'");
        format.literal(-45.13).should.equal("'-45.13'");
        format.literal('hello world').should.equal("'hello world'");
        format.literal(testArray).should.equal("'abc','1','t',NULL,'2012-12-14 13:06:43.152+00'");
        format.literal(testDate).should.equal("'2012-12-14 13:06:43.152+00'");
        format.literal(testObject).should.equal("'{\"a\":1,\"b\":2}'");
    });

    it('should format quotes', function() {
        format.literal("O'Reilly").should.equal("'O''Reilly'");
    });

    it('should format backslashes', function() {
        format.literal('\\whoop\\').should.equal("E'\\\\whoop\\\\'");
    });
});<|endoftext|>


<commit_before>var TimeIt = require('../');
var expect = require('chai').expect;

describe('Test TimeIt', function() {
  it('Should time things accurately', function(done) {
    TimeIt.time('test');
    setTimeout(function() {
      var duration = TimeIt.timeEnd('test', true);
      expect(duration).to.be.above(0.050).and.to.be.below(0.056);
      done();
    }, 50);
  });

  it('Should track several timers at the same time', function(done) {
    var iAmDone = after(100, done);

    for (var i = 0; i < 100; i++) {
      (function(i) {
        var label = 'test-' + i;
        TimeIt.time(label);
        setTimeout(function() {
          var duration = TimeIt.timeEnd(label, true);
          var min = (i / 1000) - 0.002;
          var max = (i / 1000) + 0.002;
          expect(duration).to.be.above(min).and.to.be.below(max);
          iAmDone();
        }, i);
      })(i);
    };
  });
});

function after(n, func) {
  return function() {
    if (--n < 1){
      return func.apply(this, arguments);
    }
  }
}
<commit_msg>Adjusted thresholds for testing.<commit_after>var TimeIt = require('../');
var expect = require('chai').expect;

describe('Test TimeIt', function() {
  it('Should time things accurately', function(done) {
    TimeIt.time('test');
    setTimeout(function() {
      var duration = TimeIt.timeEnd('test', true);
      expect(duration).to.be.above(0.050).and.to.be.below(0.056);
      done();
    }, 50);
  });

  it('Should track several timers at the same time', function(done) {
    var iAmDone = after(100, done);

    for (var i = 0; i < 100; i++) {
      (function(i) {
        var label = 'test-' + i;
        TimeIt.time(label);
        setTimeout(function() {
          var duration = TimeIt.timeEnd(label, true);
          var min = (i / 1000) - 0.005;
          var max = (i / 1000) + 0.005;
          expect(duration).to.be.above(min).and.to.be.below(max);
          iAmDone();
        }, i);
      })(i);
    };
  });
});

function after(n, func) {
  return function() {
    if (--n < 1){
      return func.apply(this, arguments);
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

var test = require('tape');
var VirtualScroll = require('../src/index.js');
var trigger = require('tiny-trigger');

var KEY_CODE = {
  DOWN: 40,
  SPACE: 32
}
var el = document.createElement('div');
el.style.position = 'absolute';
el.style.width = '400px';
el.style.height = '400px';
el.style.backgroundColor = 'red';
document.body.appendChild(el);

test('Scroll with target test', function(assert) {
    var v = new VirtualScroll({
        el: el
    });

    v.on(function(event) {
        if (event.originalEvent.type == 'wheel') {
            if (event.originalEvent.currentTarget == el) {
                assert.pass('Wheel events should only fire when hovering the target element.');
            } else {
                assert.fail('A wheel event fired on a different element.');
            }
            v.destroy();
            assert.end();
        }
    });

    trigger(el, 'wheel');
});

test('Arrow scroll test', function(assert) {
    var v = new VirtualScroll();

    v.on(function(event) {
        if (event.originalEvent.type == 'keydown') {
            assert.pass('Event triggered by keydown.');
            v.destroy();
            assert.end();
        }
    });

    triggerKeyboard(KEY_CODE.DOWN);
});

test('Space keypress', function(assert) {
    var v = new VirtualScroll();

    v.on(function(event) {
        if (!event.originalEvent.shiftKey && event.originalEvent.keyCode == KEY_CODE.SPACE) {
            assert.pass('Event triggered by space key.');
            v.destroy();
            assert.end();
        }
    });

    triggerKeyboard(KEY_CODE.SPACE);
});

test('Shift keypress', function(assert) {
    var v = new VirtualScroll();

    v.on(function(event) {
        if (event.originalEvent.shiftKey && event.originalEvent.keyCode == KEY_CODE.SPACE) {
            assert.pass('Event triggered by space and shift key.');
            v.destroy();
            assert.end();
        }
    });
    triggerKeyboardWithShift(KEY_CODE.SPACE);
});

test('Off test', function(assert) {
    var v = new VirtualScroll();
    var scrollCount = 0;

    var onScroll = function(event) {
        scrollCount++;
        v.off(onScroll);
    };

    v.on(onScroll);
    trigger(el, 'wheel');
    trigger(el, 'wheel');

    assert.ok(scrollCount === 1, 'Scroll handler should have fired only once.');
    assert.end();
});

test('Destroy test', function(assert) {
    var v = new VirtualScroll();
    var scrollCount = 0;

    var onScroll = function(event) {
        scrollCount++;
        v.destroy();
    };

    v.on(onScroll);
    trigger(el, 'wheel');
    trigger(el, 'wheel');

    assert.ok(scrollCount === 1, 'Scroll handler should have fired only once.');
    assert.end();
});

function triggerKeyboard(keyCode, shiftKeyPressed) {
    var event = document.createEvent('KeyboardEvent');
    Object.defineProperty(event, 'keyCode', {
        get: function() {
            return keyCode;
        }
    });
    Object.defineProperty(event, 'which', {
        get: function() {
            return keyCode;
        }
    });
    if (event.initKeyboardEvent) {
        event.initKeyboardEvent("keydown", true, true, document.defaultView, keyCode, keyCode, "", "", shiftKeyPressed ? "shift" : "", "");
    } else {
        event.initKeyEvent("keydown", true, true, document.defaultView, false, false, shiftKeyPressed, false, keyCode, 0);
    }
    document.dispatchEvent(event);
}

function triggerKeyboardWithShift(keyCode) {
  return triggerKeyboard(keyCode, true)
}
<commit_msg>rewrote shift typo to "shift and space"<commit_after>'use strict';

var test = require('tape');
var VirtualScroll = require('../src/index.js');
var trigger = require('tiny-trigger');

var KEY_CODE = {
  DOWN: 40,
  SPACE: 32
}
var el = document.createElement('div');
el.style.position = 'absolute';
el.style.width = '400px';
el.style.height = '400px';
el.style.backgroundColor = 'red';
document.body.appendChild(el);

test('Scroll with target test', function(assert) {
    var v = new VirtualScroll({
        el: el
    });

    v.on(function(event) {
        if (event.originalEvent.type == 'wheel') {
            if (event.originalEvent.currentTarget == el) {
                assert.pass('Wheel events should only fire when hovering the target element.');
            } else {
                assert.fail('A wheel event fired on a different element.');
            }
            v.destroy();
            assert.end();
        }
    });

    trigger(el, 'wheel');
});

test('Arrow scroll test', function(assert) {
    var v = new VirtualScroll();

    v.on(function(event) {
        if (event.originalEvent.type == 'keydown') {
            assert.pass('Event triggered by keydown.');
            v.destroy();
            assert.end();
        }
    });

    triggerKeyboard(KEY_CODE.DOWN);
});

test('Space keypress', function(assert) {
    var v = new VirtualScroll();

    v.on(function(event) {
        if (!event.originalEvent.shiftKey && event.originalEvent.keyCode == KEY_CODE.SPACE) {
            assert.pass('Event triggered by space key.');
            v.destroy();
            assert.end();
        }
    });

    triggerKeyboard(KEY_CODE.SPACE);
});

test('Shift and space keypress', function(assert) {
    var v = new VirtualScroll();

    v.on(function(event) {
        if (event.originalEvent.shiftKey && event.originalEvent.keyCode == KEY_CODE.SPACE) {
            assert.pass('Event triggered by space and shift key.');
            v.destroy();
            assert.end();
        }
    });
    triggerKeyboardWithShift(KEY_CODE.SPACE);
});

test('Off test', function(assert) {
    var v = new VirtualScroll();
    var scrollCount = 0;

    var onScroll = function(event) {
        scrollCount++;
        v.off(onScroll);
    };

    v.on(onScroll);
    trigger(el, 'wheel');
    trigger(el, 'wheel');

    assert.ok(scrollCount === 1, 'Scroll handler should have fired only once.');
    assert.end();
});

test('Destroy test', function(assert) {
    var v = new VirtualScroll();
    var scrollCount = 0;

    var onScroll = function(event) {
        scrollCount++;
        v.destroy();
    };

    v.on(onScroll);
    trigger(el, 'wheel');
    trigger(el, 'wheel');

    assert.ok(scrollCount === 1, 'Scroll handler should have fired only once.');
    assert.end();
});

function triggerKeyboard(keyCode, shiftKeyPressed) {
    var event = document.createEvent('KeyboardEvent');
    Object.defineProperty(event, 'keyCode', {
        get: function() {
            return keyCode;
        }
    });
    Object.defineProperty(event, 'which', {
        get: function() {
            return keyCode;
        }
    });
    if (event.initKeyboardEvent) {
        event.initKeyboardEvent("keydown", true, true, document.defaultView, keyCode, keyCode, "", "", shiftKeyPressed ? "shift" : "", "");
    } else {
        event.initKeyEvent("keydown", true, true, document.defaultView, false, false, shiftKeyPressed, false, keyCode, 0);
    }
    document.dispatchEvent(event);
}

function triggerKeyboardWithShift(keyCode) {
  return triggerKeyboard(keyCode, true)
}
<|endoftext|>


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

var pull = require('pull-stream')
var tape = require('tape')
var decode = require('../').decode

var varstruct = require('varstruct')

var struct = varstruct({
  random: varstruct.varint,
  length: varstruct.varint,
  buffer: varstruct.varbuf(varstruct.varint)
})

var n = 0
function random () {
  var l =~~(Math.random()*40)
  var b = new Buffer(l)
  b.fill(++n)
  return {
    random: ~~(Math.random()*100000000),
    buffer: b,
    length: l
  }
}

function readRandom () {
  var buffer, ended
  return function (read) {
    return function (abort, cb) {
      if(abort) return read(abort, cb)
      if(ended) return cb(ended)
      read(null, function (end, data) {
        if(end) {
          ended = end
          if(buffer.length)
            return cb(null, buffer)
          return cb(ended)
        }
        //copy twice, this isn't efficient,
        //but this is just for testing.
        if(buffer)
          buffer = Buffer.concat([buffer, data])
        else
          buffer = data

        var offset =  ~~(Math.random() * buffer.length)
        data = buffer.slice(0, offset)
        buffer = buffer.slice(offset)
        cb(null, data)
      })
    }
  }
}

tape('simple', function (t) {

  pull(
    pull.count(1),
    pull.map(random),
    pull.collect(function (err, ary) {
      var buffer = Buffer.concat(ary.map(function (v) {
          return struct.encode(v)
        }))

      var o = ~~(Math.random()*buffer.length)

      pull(
        pull.values([buffer.slice(0, o), buffer.slice(o)]),
        decode(struct),
        pull.through(console.log),
        pull.collect(function (err, _ary) {
          console.log(_ary)
          t.deepEqual(_ary, ary)
          t.end()
        })
      )
    })
  )

})
<commit_msg>add a better test<commit_after>
var crypto = require('crypto')

var pull = require('pull-stream')
var tape = require('tape')
var pv = require('../')
var decode = pv.decode
var encode = pv.encode

var varstruct = require('varstruct')

var struct = varstruct({
  random: varstruct.varint,
  length: varstruct.varint,
  buffer: varstruct.varbuf(varstruct.varint)
})

var n = 0
function random () {
  var l =~~(Math.random()*40)
  var b = new Buffer(l)
  b.fill(++n)
  return {
    random: ~~(Math.random()*100000000),
    buffer: b,
    length: l
  }
}

function readRandom () {
  var buffer, ended
  return function (read) {
    return function (abort, cb) {
      if(abort) return read(abort, cb)
      if(ended) return cb(ended)
      read(null, function (end, data) {
        if(end) {
          ended = end
          if(buffer.length)
            return cb(null, buffer)
          return cb(ended)
        }
        //copy twice, this isn't efficient,
        //but this is just for testing.
        if(buffer)
          buffer = Buffer.concat([buffer, data])
        else
          buffer = data

        var offset =  ~~(Math.random() * buffer.length)
        data = buffer.slice(0, offset)
        buffer = buffer.slice(offset)
        cb(null, data)
      })
    }
  }
}

tape('simple', function (t) {

  pull(
    pull.count(100),
    pull.map(random),
    pull.collect(function (err, ary) {
      var buffer = Buffer.concat(ary.map(function (v) {
          return struct.encode(v)
        }))

      var o = ~~(Math.random()*buffer.length)

      pull(
        pull.values([buffer.slice(0, o), buffer.slice(o)]),
        decode(struct),
        pull.through(console.log),
        pull.collect(function (err, _ary) {
          console.log(_ary)
          t.deepEqual(_ary, ary)
          t.end()
        })
      )
    })
  )

})

tape('simple', function (t) {

  var ary = []

  pull(
    pull.count(100),
    pull.map(random),
    pull.through(function (v) { ary.push(v) }),
    encode(struct),
    readRandom(),
    decode(struct),
    pull.collect(function (err, _ary) {
      console.log(_ary)
      t.deepEqual(_ary, ary)
      t.end()
    })
  )

})

<|endoftext|>