<commit_before>var chai = require('chai');
var program = require('commander');
var fs = require('fs');
var Hoek = require('hoek');
var lambda = require('../lib/main');
var fs = require('fs');
var _ = require('lodash');
var zip = require('node-zip');
var rimraf = require('rimraf');

var assert = chai.assert;

var originalProgram = {
  environment: 'development',
  accessKey: 'key',
  secretKey: 'secret',
  sessionToken: 'token',
  functionName: 'node-lambda',
  handler: 'index.handler',
  role: 'some:arn:aws:iam::role',
  memorySize: 128,
  timeout: 3,
  description: '',
  runtime: 'nodejs6.10',
  deadLetterConfigTargetArn: '',
  region: 'us-east-1,us-west-2,eu-west-1',
  eventFile: 'event.json',
  contextFile: 'context.json',
  prebuiltDirectory: '',
};

var codeDirectory = lambda._codeDirectory(program);

describe('node-lambda', function () {
  beforeEach(function () {
    program = Hoek.clone(originalProgram);
  });

  it('version should be set', function () {
    assert.equal(lambda.version, '0.8.15');
  });

  describe('_params', function () {
    it('appends environment to original functionName', function () {
      var params = lambda._params(program);
      assert.equal(params.FunctionName, 'node-lambda-development');
    });

    it('appends environment to original functionName (production)', function () {
      program.environment = 'production';
      var params = lambda._params(program);
      assert.equal(params.FunctionName, 'node-lambda-production');
    });

    it('appends version to original functionName', function () {
      program.lambdaVersion = '2015-02-01';
      var params = lambda._params(program);
      assert.equal(params.FunctionName, 'node-lambda-development-2015-02-01');
    });

    it('appends VpcConfig to params when vpc params set', function() {
      program.vpcSubnets = 'subnet-00000000,subnet-00000001,subnet-00000002';
      program.vpcSecurityGroups = 'sg-00000000,sg-00000001,sg-00000002';
      var params = lambda._params(program);
      assert.equal(params.VpcConfig.SubnetIds[0], program.vpcSubnets.split(',')[0]);
      assert.equal(params.VpcConfig.SubnetIds[1], program.vpcSubnets.split(',')[1]);
      assert.equal(params.VpcConfig.SubnetIds[2], program.vpcSubnets.split(',')[2]);
      assert.equal(params.VpcConfig.SecurityGroupIds[0], program.vpcSecurityGroups.split(',')[0]);
      assert.equal(params.VpcConfig.SecurityGroupIds[1], program.vpcSecurityGroups.split(',')[1]);
      assert.equal(params.VpcConfig.SecurityGroupIds[2], program.vpcSecurityGroups.split(',')[2]);
    });

    it('does not append VpcConfig when params are not set', function() {
      var params = lambda._params(program);
      assert.equal(Object.keys(params.VpcConfig.SubnetIds).length, 0);
      assert.equal(Object.keys(params.VpcConfig.SecurityGroupIds).length, 0);
    });

    describe('configFile', function () {
      beforeEach(function () {
        // Prep...
        fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
      });

      afterEach(function () {
        fs.unlinkSync('tmp.env');
      });

      it('adds variables when configFile param is set', function () {
        program.configFile = 'tmp.env';
        var params = lambda._params(program);
        assert.equal(params.Environment.Variables['FOO'], "bar");
        assert.equal(params.Environment.Variables['BAZ'], "bing");
      });

      it('does not add when configFile param is not set', function () {
        var params = lambda._params(program);
        assert.equal(Object.keys(params.Environment.Variables).length, 0);
      });
    });
  });

  describe('_zipfileTmpPath', function () {
    it('has the correct path', function () {
      var zipfileTmpPath = lambda._zipfileTmpPath(program);
      var value = zipfileTmpPath.indexOf(program.functionName) > 0;
      assert.equal(value, true);
    });
  });

  describe('_rsync', function () {
    beforeEach(function (done) {
      lambda._cleanDirectory(codeDirectory, done);
    });

    it('rsync an index.js as well as other files', function (done) {
      lambda._rsync(program, '.', codeDirectory, true, function (err, result) {
        var contents = fs.readdirSync(codeDirectory);

        result = _.includes(contents, 'index.js') &&
                 _.includes(contents, 'package.json') &&
                 !_.includes(contents, 'node_modules');
        assert.equal(result, true);

        done();
      });
    });

    describe("when there are excluded files", function () {
      beforeEach(function (done) {
        program.excludeGlobs="*.png test";
        done();
      });

      it('rsync an index.js as well as other files', function (done) {
        lambda._rsync(program, '.', codeDirectory, true, function (err, result) {
          var contents = fs.readdirSync(codeDirectory);

          result = _.includes(contents, 'index.js') &&
                   _.includes(contents, 'package.json');
          assert.equal(result, true);

          done();
        });
      });

      it('rsync excludes files matching excludeGlobs', function (done) {
        lambda._rsync(program, '.', codeDirectory, true, function (err, result) {
          var contents = fs.readdirSync(codeDirectory);

          result = _.includes(contents, 'node-lambda.png') &&
                   _.includes(contents, 'test');
          assert.equal(result, false);

          done();
        });
      });

      it('rsync should not exclude package.json, even when excluded by excludeGlobs', function (done) {
        program.excludeGlobs="*.json"
        lambda._rsync(program, '.', codeDirectory, true, function(err, result) {
          var contents = fs.readdirSync(codeDirectory);
          result = _.includes(contents, 'package.json');
          assert.equal(result, true);

          done();
        });
      });

      it('rsync should not include package.json when --prebuiltDirectory is set', function (done) {
        var path = '.build_' + Date.now();
        after(function() {
          rimraf.sync(path, fs);
        });

        fs.mkdirSync(path);
        fs.writeFileSync(path + '/testa');
        fs.writeFileSync(path + '/package.json');

        program.excludeGlobs = "*.json"
        program.prebuiltDirectory = path;
        lambda._rsync(program, path, codeDirectory, true, function(err, result) {
          var contents = fs.readdirSync(codeDirectory);
          result = !_.includes(contents, 'package.json') &&
                    _.includes(contents, 'testa');
          assert.equal(result, true);

          done();
        });
      });
    });
  });

  describe('_npmInstall', function () {
    beforeEach(function (done) {
      lambda._cleanDirectory(codeDirectory, function (err) {
        if (err) {
          return done(err);
        }

        lambda._rsync(program, '.', codeDirectory, true, function (err) {
          if (err) {
            return done(err);
          }
          done();
        });
      });
    });

    it('_npm adds node_modules', function (done) {
      this.timeout(60000); // give it time to build the node modules

      lambda._npmInstall(program, codeDirectory, function (err, result) {
        var contents = fs.readdirSync(codeDirectory);

        result = _.includes(contents, 'node_modules');
        assert.equal(result, true);

        done();
      });
    });
  });

  describe('_postInstallScript', function () {
    var hook;
    /**
     * Capture console output
     */
    function captureStream(stream){
      var oldWrite = stream.write;
      var buf = '';
      stream.write = function(chunk, encoding, callback){
        buf += chunk.toString(); // chunk is a String or Buffer
        oldWrite.apply(stream, arguments);
      }

      return {
        unhook: function unhook(){
         stream.write = oldWrite;
        },
        captured: function(){
          return buf;
        }
      };
    }
    beforeEach(function(){
      hook = captureStream(process.stdout);
    });
    afterEach(function(){
      hook.unhook();
    });

    it('should not throw any errors if no script', function (done) {
      lambda._postInstallScript(program, codeDirectory, function (err) {
        assert.equal(err, null);
        done();
      });
    });

    it('running script gives expected output', function (done) {
      fs.writeFileSync(codeDirectory + '/post_install.sh', fs.readFileSync('test/post_install.sh'));
      fs.chmodSync(codeDirectory + '/post_install.sh', '755');
      lambda._postInstallScript(program, codeDirectory, function (err) {
        assert.equal(err, null);
        assert.equal("=> Running post install script post_install.sh\n\t\tYour environment is "+program.environment+"\n", hook.captured());
        fs.unlinkSync(codeDirectory + '/post_install.sh');
        done();
      });
    });
  });

  describe('_zip', function () {
    beforeEach(function (done) {
      this.timeout(30000); // give it time to build the node modules
      lambda._cleanDirectory(codeDirectory, function (err) {
        if (err) {
          return done(err);
        }

        lambda._rsync(program, '.', codeDirectory, true, function (err) {
          if (err) {
            return done(err);
          }
          lambda._npmInstall(program, codeDirectory, function (err) {
            if (err) {
              return done(err);
            }
            done();
          });
        });
      });
    });

    it('zips the file and has an index.js file', function (done) {
      this.timeout(30000); // give it time to zip

      lambda._zip(program, codeDirectory, function (err, data) {
        var archive = new zip(data);
        var contents = _.map(archive.files, function (f) {
          return f.name.toString();
        });
        var result = _.includes(contents, 'index.js');
        assert.equal(result, true);

        done();
      });
    });
  });

  describe('_archive', function () {
    it('installs and zips with an index.js file and node_modules/async', function (done) {
      this.timeout(30000); // give it time to zip

      lambda._archive(program, function (err, data) {
        var archive = new zip(data);
        var contents = _.map(archive.files, function (f) {
          return f.name.toString();
        });
        var result = _.includes(contents, 'index.js');
        assert.equal(result, true);
        result = _.includes(contents, 'node_modules/async/lib/async.js');
        assert.equal(result, true);
        done();
      });
    });

    it('packages a prebuilt module without installing', function (done) {
      var path = '.build_' + Date.now();
      after(function() {
        rimraf.sync(path, fs);
      });

      fs.mkdirSync(path);
      fs.mkdirSync(path + '/d');
      fs.mkdirSync(path + '/node_modules');
      fs.writeFileSync(path + '/node_modules/a', '...');
      fs.writeFileSync(path + '/testa', '...');
      fs.writeFileSync(path + '/d/testb', '...');

      program.prebuiltDirectory = path;
      lambda._archive(program, function (err, data) {
        var archive = new zip(data);
        var contents = _.map(archive.files, function (f) {
          return f.name.toString();
        });
        var result = _.includes(contents, 'testa') &&
                     _.includes(contents, 'd/testb') &&
                     _.includes(contents, 'node_modules/a');
        assert.equal(result, true);
        done();
      });
    });
  });

  describe('_readArchive', function () {
    const testZipFile = '/tmp/node-lambda-test.zip';
    var bufferExpected = null;
    before(function(done) {
      this.timeout(30000); // give it time to zip

      lambda._zip(program, codeDirectory, function (err, data) {
        bufferExpected = data;
        fs.writeFileSync(testZipFile, data);
        done();
      });
    });

    after(function() {
      fs.unlinkSync(testZipFile);
    });

    it('_readArchive fails (undefined)', function (done) {
      lambda._readArchive(program, function (err, data) {
        assert.isUndefined(data);
        assert.instanceOf(err, Error);
        assert.equal(err.message, 'No such Zipfile [undefined]');
        done();
      });
    });

    it('_readArchive fails (does not exists file)', function (done) {
      const _program = Object.assign({ deployZipfile: '/aaaa/bbbb' }, program);
      lambda._readArchive(_program, function (err, data) {
        assert.isUndefined(data);
        assert.instanceOf(err, Error);
        assert.equal(err.message, 'No such Zipfile [/aaaa/bbbb]');
        done();
      });
    });

    it('_readArchive reads the contents of the zipfile', function (done) {
      const _program = Object.assign({ deployZipfile: testZipFile }, program);
      lambda._readArchive(_program, function (err, data) {
        assert.isNull(err);
        assert.deepEqual(data, bufferExpected);
        done();
      });
    });
  });

  describe('environment variable injection at runtime', function () {
    beforeEach(function () {
      // Prep...
      fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
    });

    afterEach(function () {
      fs.unlinkSync('tmp.env');
    });

    it('should inject environment variables at runtime', function () {

      // Run it...
      lambda._setRunTimeEnvironmentVars({
        configFile: 'tmp.env'
      }, process.cwd());

      assert.equal(process.env["FOO"], 'bar');
      assert.equal(process.env["BAZ"], 'bing');
    });

  });

  describe('create sample files', function () {

    afterEach(function () {
      fs.unlinkSync('.env');
      fs.unlinkSync('context.json');
      fs.unlinkSync('event.json');
      fs.unlinkSync('deploy.env');
    });

    it('should create sample files', function () {
      lambda.setup(program);

      var envBoilerplateFile = __dirname + '/../lib/.env.example';
      var contextBoilerplateFile = __dirname + '/../lib/context.json.example';
      var eventBoilerplateFile = __dirname + '/../lib/event.json.example';
      var deployBoilerplateFile = __dirname + '/../lib/deploy.env.example';

      assert.equal(fs.readFileSync('.env').toString(), fs.readFileSync(envBoilerplateFile).toString());
      assert.equal(fs.readFileSync('context.json').toString(), fs.readFileSync(contextBoilerplateFile).toString());
      assert.equal(fs.readFileSync('event.json').toString(), fs.readFileSync(eventBoilerplateFile).toString());
      assert.equal(fs.readFileSync('deploy.env').toString(), fs.readFileSync(deployBoilerplateFile).toString());
    });
  });

  describe('check env vars before create sample files', function () {

    beforeEach(function () {
      fs.writeFileSync('newContext.json', '{"FOO"="bar"\n"BAZ"="bing"\n}');
      fs.writeFileSync('newEvent.json', '{"FOO"="bar"}');
    });

    afterEach(function () {
      fs.unlinkSync('.env');
      fs.unlinkSync('newContext.json');
      fs.unlinkSync('newEvent.json');
      fs.unlinkSync('deploy.env');
    });

    it('should use existing sample files', function () {
      program.eventFile = 'newEvent.json';
      program.contextFile = 'newContext.json';

      lambda.setup(program);

      var envBoilerplateFile = __dirname + '/../lib/.env.example';
      var deployBoilerplateFile = __dirname + '/../lib/deploy.env.example';

      assert.equal(fs.readFileSync('.env').toString(), fs.readFileSync(envBoilerplateFile).toString());
      assert.equal(fs.readFileSync('newContext.json').toString(), '{"FOO"="bar"\n"BAZ"="bing"\n}');
      assert.equal(fs.readFileSync('newEvent.json').toString(), '{"FOO"="bar"}');
      assert.equal(fs.readFileSync('deploy.env').toString(), fs.readFileSync(deployBoilerplateFile).toString());
    });

  });
});
<commit_msg>Add tests for event_sources.json (#214)<commit_after>var chai = require('chai');
var program = require('commander');
var fs = require('fs');
var Hoek = require('hoek');
var lambda = require('../lib/main');
var fs = require('fs');
var _ = require('lodash');
var zip = require('node-zip');
var rimraf = require('rimraf');

var assert = chai.assert;

var originalProgram = {
  environment: 'development',
  accessKey: 'key',
  secretKey: 'secret',
  sessionToken: 'token',
  functionName: 'node-lambda',
  handler: 'index.handler',
  role: 'some:arn:aws:iam::role',
  memorySize: 128,
  timeout: 3,
  description: '',
  runtime: 'nodejs6.10',
  deadLetterConfigTargetArn: '',
  region: 'us-east-1,us-west-2,eu-west-1',
  eventFile: 'event.json',
  contextFile: 'context.json',
  prebuiltDirectory: '',
};

var codeDirectory = lambda._codeDirectory(program);

describe('node-lambda', function () {
  beforeEach(function () {
    program = Hoek.clone(originalProgram);
  });

  it('version should be set', function () {
    assert.equal(lambda.version, '0.8.15');
  });

  describe('_params', function () {
    it('appends environment to original functionName', function () {
      var params = lambda._params(program);
      assert.equal(params.FunctionName, 'node-lambda-development');
    });

    it('appends environment to original functionName (production)', function () {
      program.environment = 'production';
      var params = lambda._params(program);
      assert.equal(params.FunctionName, 'node-lambda-production');
    });

    it('appends version to original functionName', function () {
      program.lambdaVersion = '2015-02-01';
      var params = lambda._params(program);
      assert.equal(params.FunctionName, 'node-lambda-development-2015-02-01');
    });

    it('appends VpcConfig to params when vpc params set', function() {
      program.vpcSubnets = 'subnet-00000000,subnet-00000001,subnet-00000002';
      program.vpcSecurityGroups = 'sg-00000000,sg-00000001,sg-00000002';
      var params = lambda._params(program);
      assert.equal(params.VpcConfig.SubnetIds[0], program.vpcSubnets.split(',')[0]);
      assert.equal(params.VpcConfig.SubnetIds[1], program.vpcSubnets.split(',')[1]);
      assert.equal(params.VpcConfig.SubnetIds[2], program.vpcSubnets.split(',')[2]);
      assert.equal(params.VpcConfig.SecurityGroupIds[0], program.vpcSecurityGroups.split(',')[0]);
      assert.equal(params.VpcConfig.SecurityGroupIds[1], program.vpcSecurityGroups.split(',')[1]);
      assert.equal(params.VpcConfig.SecurityGroupIds[2], program.vpcSecurityGroups.split(',')[2]);
    });

    it('does not append VpcConfig when params are not set', function() {
      var params = lambda._params(program);
      assert.equal(Object.keys(params.VpcConfig.SubnetIds).length, 0);
      assert.equal(Object.keys(params.VpcConfig.SecurityGroupIds).length, 0);
    });

    describe('configFile', function () {
      beforeEach(function () {
        // Prep...
        fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
      });

      afterEach(function () {
        fs.unlinkSync('tmp.env');
      });

      it('adds variables when configFile param is set', function () {
        program.configFile = 'tmp.env';
        var params = lambda._params(program);
        assert.equal(params.Environment.Variables['FOO'], "bar");
        assert.equal(params.Environment.Variables['BAZ'], "bing");
      });

      it('does not add when configFile param is not set', function () {
        var params = lambda._params(program);
        assert.equal(Object.keys(params.Environment.Variables).length, 0);
      });
    });
  });

  describe('_zipfileTmpPath', function () {
    it('has the correct path', function () {
      var zipfileTmpPath = lambda._zipfileTmpPath(program);
      var value = zipfileTmpPath.indexOf(program.functionName) > 0;
      assert.equal(value, true);
    });
  });

  describe('_rsync', function () {
    beforeEach(function (done) {
      lambda._cleanDirectory(codeDirectory, done);
    });

    it('rsync an index.js as well as other files', function (done) {
      lambda._rsync(program, '.', codeDirectory, true, function (err, result) {
        var contents = fs.readdirSync(codeDirectory);

        result = _.includes(contents, 'index.js') &&
                 _.includes(contents, 'package.json') &&
                 !_.includes(contents, 'node_modules');
        assert.equal(result, true);

        done();
      });
    });

    describe("when there are excluded files", function () {
      beforeEach(function (done) {
        program.excludeGlobs="*.png test";
        done();
      });

      it('rsync an index.js as well as other files', function (done) {
        lambda._rsync(program, '.', codeDirectory, true, function (err, result) {
          var contents = fs.readdirSync(codeDirectory);

          result = _.includes(contents, 'index.js') &&
                   _.includes(contents, 'package.json');
          assert.equal(result, true);

          done();
        });
      });

      it('rsync excludes files matching excludeGlobs', function (done) {
        lambda._rsync(program, '.', codeDirectory, true, function (err, result) {
          var contents = fs.readdirSync(codeDirectory);

          result = _.includes(contents, 'node-lambda.png') &&
                   _.includes(contents, 'test');
          assert.equal(result, false);

          done();
        });
      });

      it('rsync should not exclude package.json, even when excluded by excludeGlobs', function (done) {
        program.excludeGlobs="*.json"
        lambda._rsync(program, '.', codeDirectory, true, function(err, result) {
          var contents = fs.readdirSync(codeDirectory);
          result = _.includes(contents, 'package.json');
          assert.equal(result, true);

          done();
        });
      });

      it('rsync should not include package.json when --prebuiltDirectory is set', function (done) {
        var path = '.build_' + Date.now();
        after(function() {
          rimraf.sync(path, fs);
        });

        fs.mkdirSync(path);
        fs.writeFileSync(path + '/testa');
        fs.writeFileSync(path + '/package.json');

        program.excludeGlobs = "*.json"
        program.prebuiltDirectory = path;
        lambda._rsync(program, path, codeDirectory, true, function(err, result) {
          var contents = fs.readdirSync(codeDirectory);
          result = !_.includes(contents, 'package.json') &&
                    _.includes(contents, 'testa');
          assert.equal(result, true);

          done();
        });
      });
    });
  });

  describe('_npmInstall', function () {
    beforeEach(function (done) {
      lambda._cleanDirectory(codeDirectory, function (err) {
        if (err) {
          return done(err);
        }

        lambda._rsync(program, '.', codeDirectory, true, function (err) {
          if (err) {
            return done(err);
          }
          done();
        });
      });
    });

    it('_npm adds node_modules', function (done) {
      this.timeout(60000); // give it time to build the node modules

      lambda._npmInstall(program, codeDirectory, function (err, result) {
        var contents = fs.readdirSync(codeDirectory);

        result = _.includes(contents, 'node_modules');
        assert.equal(result, true);

        done();
      });
    });
  });

  describe('_postInstallScript', function () {
    var hook;
    /**
     * Capture console output
     */
    function captureStream(stream){
      var oldWrite = stream.write;
      var buf = '';
      stream.write = function(chunk, encoding, callback){
        buf += chunk.toString(); // chunk is a String or Buffer
        oldWrite.apply(stream, arguments);
      }

      return {
        unhook: function unhook(){
         stream.write = oldWrite;
        },
        captured: function(){
          return buf;
        }
      };
    }
    beforeEach(function(){
      hook = captureStream(process.stdout);
    });
    afterEach(function(){
      hook.unhook();
    });

    it('should not throw any errors if no script', function (done) {
      lambda._postInstallScript(program, codeDirectory, function (err) {
        assert.equal(err, null);
        done();
      });
    });

    it('running script gives expected output', function (done) {
      fs.writeFileSync(codeDirectory + '/post_install.sh', fs.readFileSync('test/post_install.sh'));
      fs.chmodSync(codeDirectory + '/post_install.sh', '755');
      lambda._postInstallScript(program, codeDirectory, function (err) {
        assert.equal(err, null);
        assert.equal("=> Running post install script post_install.sh\n\t\tYour environment is "+program.environment+"\n", hook.captured());
        fs.unlinkSync(codeDirectory + '/post_install.sh');
        done();
      });
    });
  });

  describe('_zip', function () {
    beforeEach(function (done) {
      this.timeout(30000); // give it time to build the node modules
      lambda._cleanDirectory(codeDirectory, function (err) {
        if (err) {
          return done(err);
        }

        lambda._rsync(program, '.', codeDirectory, true, function (err) {
          if (err) {
            return done(err);
          }
          lambda._npmInstall(program, codeDirectory, function (err) {
            if (err) {
              return done(err);
            }
            done();
          });
        });
      });
    });

    it('zips the file and has an index.js file', function (done) {
      this.timeout(30000); // give it time to zip

      lambda._zip(program, codeDirectory, function (err, data) {
        var archive = new zip(data);
        var contents = _.map(archive.files, function (f) {
          return f.name.toString();
        });
        var result = _.includes(contents, 'index.js');
        assert.equal(result, true);

        done();
      });
    });
  });

  describe('_archive', function () {
    it('installs and zips with an index.js file and node_modules/async', function (done) {
      this.timeout(30000); // give it time to zip

      lambda._archive(program, function (err, data) {
        var archive = new zip(data);
        var contents = _.map(archive.files, function (f) {
          return f.name.toString();
        });
        var result = _.includes(contents, 'index.js');
        assert.equal(result, true);
        result = _.includes(contents, 'node_modules/async/lib/async.js');
        assert.equal(result, true);
        done();
      });
    });

    it('packages a prebuilt module without installing', function (done) {
      var path = '.build_' + Date.now();
      after(function() {
        rimraf.sync(path, fs);
      });

      fs.mkdirSync(path);
      fs.mkdirSync(path + '/d');
      fs.mkdirSync(path + '/node_modules');
      fs.writeFileSync(path + '/node_modules/a', '...');
      fs.writeFileSync(path + '/testa', '...');
      fs.writeFileSync(path + '/d/testb', '...');

      program.prebuiltDirectory = path;
      lambda._archive(program, function (err, data) {
        var archive = new zip(data);
        var contents = _.map(archive.files, function (f) {
          return f.name.toString();
        });
        var result = _.includes(contents, 'testa') &&
                     _.includes(contents, 'd/testb') &&
                     _.includes(contents, 'node_modules/a');
        assert.equal(result, true);
        done();
      });
    });
  });

  describe('_readArchive', function () {
    const testZipFile = '/tmp/node-lambda-test.zip';
    var bufferExpected = null;
    before(function(done) {
      this.timeout(30000); // give it time to zip

      lambda._zip(program, codeDirectory, function (err, data) {
        bufferExpected = data;
        fs.writeFileSync(testZipFile, data);
        done();
      });
    });

    after(function() {
      fs.unlinkSync(testZipFile);
    });

    it('_readArchive fails (undefined)', function (done) {
      lambda._readArchive(program, function (err, data) {
        assert.isUndefined(data);
        assert.instanceOf(err, Error);
        assert.equal(err.message, 'No such Zipfile [undefined]');
        done();
      });
    });

    it('_readArchive fails (does not exists file)', function (done) {
      const _program = Object.assign({ deployZipfile: '/aaaa/bbbb' }, program);
      lambda._readArchive(_program, function (err, data) {
        assert.isUndefined(data);
        assert.instanceOf(err, Error);
        assert.equal(err.message, 'No such Zipfile [/aaaa/bbbb]');
        done();
      });
    });

    it('_readArchive reads the contents of the zipfile', function (done) {
      const _program = Object.assign({ deployZipfile: testZipFile }, program);
      lambda._readArchive(_program, function (err, data) {
        assert.isNull(err);
        assert.deepEqual(data, bufferExpected);
        done();
      });
    });
  });

  describe('environment variable injection at runtime', function () {
    beforeEach(function () {
      // Prep...
      fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
    });

    afterEach(function () {
      fs.unlinkSync('tmp.env');
    });

    it('should inject environment variables at runtime', function () {

      // Run it...
      lambda._setRunTimeEnvironmentVars({
        configFile: 'tmp.env'
      }, process.cwd());

      assert.equal(process.env["FOO"], 'bar');
      assert.equal(process.env["BAZ"], 'bing');
    });

  });

  describe('create sample files', function () {
    const targetFiles = [
      '.env',
      'context.json',
      'event.json',
      'deploy.env',
      'event_sources.json'
    ];

    afterEach(function () {
      targetFiles.forEach(function(file) {
        fs.unlinkSync(file);
      });
    });

    it('should create sample files', function () {
      lambda.setup(program);

      const libPath = `${__dirname}/../lib`;
      targetFiles.forEach(function(targetFile) {
        const boilerplateFile = `${libPath}/${targetFile}.example`;

        assert.equal(
          fs.readFileSync(targetFile).toString(),
          fs.readFileSync(boilerplateFile).toString(),
          targetFile
        );
      });
    });
  });

  describe('check env vars before create sample files', function () {
    const filesCreatedBySetup = [
      '.env',
      'deploy.env',
      'event_sources.json'
    ];

    beforeEach(function () {
      fs.writeFileSync('newContext.json', '{"FOO"="bar"\n"BAZ"="bing"\n}');
      fs.writeFileSync('newEvent.json', '{"FOO"="bar"}');
    });

    afterEach(function () {
      fs.unlinkSync('newContext.json');
      fs.unlinkSync('newEvent.json');
      filesCreatedBySetup.forEach(function(file) {
        fs.unlinkSync(file);
      });
    });

    it('should use existing sample files', function () {
      program.eventFile = 'newEvent.json';
      program.contextFile = 'newContext.json';

      lambda.setup(program);

      assert.equal(fs.readFileSync('newContext.json').toString(), '{"FOO"="bar"\n"BAZ"="bing"\n}');
      assert.equal(fs.readFileSync('newEvent.json').toString(), '{"FOO"="bar"}');

      const libPath = `${__dirname}/../lib`;
      filesCreatedBySetup.forEach(function(targetFile) {
        const boilerplateFile = `${libPath}/${targetFile}.example`;

        assert.equal(
          fs.readFileSync(targetFile).toString(),
          fs.readFileSync(boilerplateFile).toString(),
          targetFile
        );
      });
    });

  });
});
<|endoftext|>


<commit_before>var assert = require('assert'),
    main;

function mockConsole() {
    var c ={
        warnings: [],
        warn: function(str) {
            c.warnings.push(str);
        },
        loggings: [],
        log: function(str) {
            c.loggings.push(str);
        }
    };

    return c;
}

function mockProcess() {
    var p = {
        argv: ['jslint'],
        exit: function (c) {
            this.exitCode = c;
            this.events.exit.forEach(function (f) {
                f();
            });
        },
        doDrain: function() {
            this.events.drain.forEach(function (f) {
                f();
            });
        },
        events: { exit: [],
                  drain: [] },
        on: function (event,f) {
            this.events[event].push(f);
        },
        stdout: {
            isTTY: true,

            /* mock: call callback right away */
            on: function (event, fn) {
                process.nextTick(function () {
                    fn();
                    p.doDrain();
                });
            },
            callbacks: {
                drain: []
            }
        }
    };
    return p;
}

function mockParsed() {
    return {
        argv: {
            remain: []
        }
    };
}

suite('jslint main', function () {
    var pro, con;

    setup(function () {
        main = require('../lib/main');

        con = mockConsole();
        pro = mockProcess();

        main.setConsole(con);
        main.setProcess(pro);
    });

    test('main - no args', function () {
        var parsed = mockParsed();

        main.runMain(parsed);

        assert.ok(main);
        assert.strictEqual(1, pro.exitCode);
        assert.strictEqual(2, con.warnings.length);
    });

    test('main - bad lint', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('test/fixtures/bad.js');

        main.runMain(parsed);

        pro.on('exit', function () {
            assert.equal(1, pro.exitCode);
            done();
        });
    });

    test('main - three files', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('lib/main.js');
        parsed.argv.remain.push('lib/main.js');
        parsed.argv.remain.push('lib/main.js');

        pro.on('exit', done);

        parsed.terse = true;

        main.runMain(parsed);

        assert.ok(main);
    });

    test('main - glob files', function (done) {
        // bail if glob not installed
        if (!main.glob) {
            assert.ok(true);
            done();
            return;
        }

        var parsed = mockParsed();

        parsed.argv.remain.push('lib/mai*.js');

        pro.on('exit', done);

        parsed.terse = true;

        main.runMain(parsed);

        assert.ok(main);
    });

    test('main - glob ignore node_modules', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('./lib/main.js');
        parsed.argv.remain.push('./node_modules/glob/*');

        pro.on('exit', done);

        parsed.terse = true;

        main.runMain(parsed);

        assert.ok(main);
    });

    test('main - one file, not tty, json output', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('lib/reporter.js');

        parsed.json = true;

        pro.stdout.isTTY = false;

        pro.on('exit', function () {
            assert.strictEqual(0, pro.exitCode);
            done();
        });

        main.runMain(parsed);

        assert.ok(main);

        // expect process.exit(0) to be as yet uncalled
        assert.strictEqual(undefined, pro.exitCode);
    });

    test('todo in command-line options', function () {
        var o = main.commandOptions();

        assert.strictEqual(Boolean, o.todo);
    });

    function isBasicType(type, value) {
        return type(value).valueOf() === value;
    }

    test('isBasicType works', function () {

        assert.ok(isBasicType(Boolean, true));
        assert.ok(isBasicType(Boolean, false));
        assert.ok(isBasicType(Number, 1));

        assert.ok(!isBasicType(Boolean, 0));
        assert.ok(!isBasicType(Boolean, 1));
        assert.ok(!isBasicType(Number, false));
        assert.ok(!isBasicType(String, 1));
        assert.ok(!isBasicType(Number, '1'));
    });

    test('example jslint.conf contains only valid options', function (done) {

        var options = main.commandOptions(),
            fs = require('fs');

        fs.readFile("jslint.conf.example", function (err, file) {
            if (err) {
                throw err;
            }

            var example = JSON.parse(file),
                keys = Object.keys(example);

            keys.forEach(function(opt) {
                assert.ok(options.hasOwnProperty(opt));

                var type = options[opt],
                    value = example[opt];

                assert.ok(isBasicType(type, value));
            });

            done();
        });
    });

    test('edition is a string (not Boolean) option', function () {
        var options = main.commandOptions();

        assert.equal(String, options.edition);
    });

    test('returns a version', function (done) {

        main.reportVersion(function (version) {

            assert.ok(/^node-jslint version:/.test(version));
            assert.ok(/  JSLint edition/.test(version));
            done();
        }, {} );
    });

    test('argument parsing: edition is a string', function () {
        var options = main.parseArgs(['node', 'jslint', '--edition=latest']);

        assert.equal('latest', options.edition);
    });

    test('main -- report version', function (done) {
        main.runMain({version: true});

        done();
    });

    test('main -- globbing with no globber', function () {
        var files = main.globFiles(['foo', 'bar'], undefined);

        assert.deepEqual(['foo', 'bar'], files);
    });

    test('main -- globbing with no globber -- removes node_modules', function () {
        var files = main.globFiles(['foo', 'node_modules/bletch.js',
                                    'bar', 'quux/node_modules/blither.js'], undefined);

        assert.deepEqual(['foo', 'bar'], files);
    });

});
<commit_msg>test: remove needless slow test<commit_after>var assert = require('assert'),
    main;

function mockConsole() {
    var c ={
        warnings: [],
        warn: function(str) {
            c.warnings.push(str);
        },
        loggings: [],
        log: function(str) {
            c.loggings.push(str);
        }
    };

    return c;
}

function mockProcess() {
    var p = {
        argv: ['jslint'],
        exit: function (c) {
            this.exitCode = c;
            this.events.exit.forEach(function (f) {
                f();
            });
        },
        doDrain: function() {
            this.events.drain.forEach(function (f) {
                f();
            });
        },
        events: { exit: [],
                  drain: [] },
        on: function (event,f) {
            this.events[event].push(f);
        },
        stdout: {
            isTTY: true,

            /* mock: call callback right away */
            on: function (event, fn) {
                process.nextTick(function () {
                    fn();
                    p.doDrain();
                });
            },
            callbacks: {
                drain: []
            }
        }
    };
    return p;
}

function mockParsed() {
    return {
        argv: {
            remain: []
        }
    };
}

suite('jslint main', function () {
    var pro, con;

    setup(function () {
        main = require('../lib/main');

        con = mockConsole();
        pro = mockProcess();

        main.setConsole(con);
        main.setProcess(pro);
    });

    test('main - no args', function () {
        var parsed = mockParsed();

        main.runMain(parsed);

        assert.ok(main);
        assert.strictEqual(1, pro.exitCode);
        assert.strictEqual(2, con.warnings.length);
    });

    test('main - bad lint', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('test/fixtures/bad.js');

        main.runMain(parsed);

        pro.on('exit', function () {
            assert.equal(1, pro.exitCode);
            done();
        });
    });

    test('main - glob files', function (done) {
        // bail if glob not installed
        if (!main.glob) {
            assert.ok(true);
            done();
            return;
        }

        var parsed = mockParsed();

        parsed.argv.remain.push('lib/mai*.js');

        pro.on('exit', done);

        parsed.terse = true;

        main.runMain(parsed);

        assert.ok(main);
    });

    test('main - glob ignore node_modules', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('./lib/main.js');
        parsed.argv.remain.push('./node_modules/glob/*');

        pro.on('exit', done);

        parsed.terse = true;

        main.runMain(parsed);

        assert.ok(main);
    });

    test('main - one file, not tty, json output', function (done) {
        var parsed = mockParsed();

        parsed.argv.remain.push('lib/reporter.js');

        parsed.json = true;

        pro.stdout.isTTY = false;

        pro.on('exit', function () {
            assert.strictEqual(0, pro.exitCode);
            done();
        });

        main.runMain(parsed);

        assert.ok(main);

        // expect process.exit(0) to be as yet uncalled
        assert.strictEqual(undefined, pro.exitCode);
    });

    test('todo in command-line options', function () {
        var o = main.commandOptions();

        assert.strictEqual(Boolean, o.todo);
    });

    function isBasicType(type, value) {
        return type(value).valueOf() === value;
    }

    test('isBasicType works', function () {

        assert.ok(isBasicType(Boolean, true));
        assert.ok(isBasicType(Boolean, false));
        assert.ok(isBasicType(Number, 1));

        assert.ok(!isBasicType(Boolean, 0));
        assert.ok(!isBasicType(Boolean, 1));
        assert.ok(!isBasicType(Number, false));
        assert.ok(!isBasicType(String, 1));
        assert.ok(!isBasicType(Number, '1'));
    });

    test('example jslint.conf contains only valid options', function (done) {

        var options = main.commandOptions(),
            fs = require('fs');

        fs.readFile("jslint.conf.example", function (err, file) {
            if (err) {
                throw err;
            }

            var example = JSON.parse(file),
                keys = Object.keys(example);

            keys.forEach(function(opt) {
                assert.ok(options.hasOwnProperty(opt));

                var type = options[opt],
                    value = example[opt];

                assert.ok(isBasicType(type, value));
            });

            done();
        });
    });

    test('edition is a string (not Boolean) option', function () {
        var options = main.commandOptions();

        assert.equal(String, options.edition);
    });

    test('returns a version', function (done) {

        main.reportVersion(function (version) {

            assert.ok(/^node-jslint version:/.test(version));
            assert.ok(/  JSLint edition/.test(version));
            done();
        }, {} );
    });

    test('argument parsing: edition is a string', function () {
        var options = main.parseArgs(['node', 'jslint', '--edition=latest']);

        assert.equal('latest', options.edition);
    });

    test('main -- report version', function (done) {
        main.runMain({version: true});

        done();
    });

    test('main -- globbing with no globber', function () {
        var files = main.globFiles(['foo', 'bar'], undefined);

        assert.deepEqual(['foo', 'bar'], files);
    });

    test('main -- globbing with no globber -- removes node_modules', function () {
        var files = main.globFiles(['foo', 'node_modules/bletch.js',
                                    'bar', 'quux/node_modules/blither.js'], undefined);

        assert.deepEqual(['foo', 'bar'], files);
    });

});
<|endoftext|>


<commit_before>/* -*- Mode: Javascript; js-indent-level: 2 -*- */

var testDatabase = require('./util/database');
var db = require('../')(testDatabase.url);

var assert = require('assert');
var async = require('async');

describe('seraph#save, seraph#read', function() {
  it('should accept id of 0 on read', function(done) {
    db.read(0, function(err, data) {
      if (err)
        assert.equal(err.statusCode, 204); // neo4j gives 204 no content
      done();
    });
  });

  it('should accept id of 0 on save', function(done) {
    db.save({ id: 0, herp: "DERP" }, function(err, data) {
      if (err)
        assert.ok(err.statusCode); // not seraph error
      done();
    });
  });

  it('should handle alternative id property name', function(done) {
    function create(done) {
      db.save({ name: 'Jon', age: 23 }, function(err, user) {
        assert.ok(!err, err);
        assert.ok(typeof user.ponies !== 'undefined');
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);

        done(null, user.ponies);
      });
    }

    function read(userId, done) {
      db.read(userId, function(err, user) {
        assert.ok(!err, err);
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);
        done(null, user);
      });
    }

    var origId = db.options.id;
    db.options.id = "ponies";
    try {
      async.waterfall([create, read], function(err, res) {
        db.options.id = origId;
        done(err, res);
      });
    } catch (e) {
      db.options.id = origId;
      throw e;
    }
  });

  it('should be able to create an object and read it back', function(done) {
    function create(done) {
      db.save({ name: 'Jon', age: 23 }, function(err, user) {
        assert.ok(!err, err);
        assert.ok(typeof user.id !== 'undefined');
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);

        done(null, user.id);
      });
    }

    function read(userId, done) {
      db.read(userId, function(err, user) {
        assert.ok(!err, err);
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);
        done(null, user);
      });
    }

    async.waterfall([create, read], done);
  });

  it('should take an array of objects to save/read', function(done) {
    function createObjs(done) {
      db.save([{name: 'Jon'}, {name: 'Helge'}], function(err, users) {
        assert.ok(!err, err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function readObjs(user1, user2, done) {
      db.read([user1.id, user2.id], function(err, users) {
        assert.ok(!err, err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done();
      });
    }

    async.waterfall([createObjs, readObjs], done);
  });

  it('should handle an empty array of objects to save', function(done) {
    db.save([], done);
  });

  it('should not introduce id fields into the database', function(done) {
    db.save({pie: 'potato'}, function(err, thing) {
      db.read(thing, function(err, thingamajig) {
        db.save(thingamajig, function(err, thingamajiggy) {
          db.query('START n = node({id}) RETURN n.id? as thingamajiggle',
                   thingamajiggy, function(err, thingamajoggle) {
            assert.ok(thingamajoggle[0] === null);
            done();
          });
        });
      });
    });
  });
})

describe('seraph#update', function() {
  it('should perform an update on an object', function(done) {
    function create(done) {
      db.save({ name: 'Jan', age: 55 }, function(err, user) {
        assert.ok(!err);
        assert.equal(user.name, 'Jan');
        assert.equal(user.age, 55);
        done(null, user);
      });
    }

    function update(user, done) {
      user.name = 'Belinda';
      user.age = 26;
      var userId = user.id;
      db.save(user, function(err, user) {
        assert.ok(!err);
        assert.equal(userId, user.id);
        assert.equal(user.name, 'Belinda');
        assert.equal(user.age, 26);
        db.read(userId, function(err, user) {
          assert.ok(!err);
          assert.equal(userId, user.id);
          assert.equal(user.name, 'Belinda');
          assert.equal(user.age, 26);
          done(null, user);
        });
      });
    }

    async.waterfall([create, update], done);
  });

  it('should take an array of objects to save/read', function(done) {
    function createObjs(done) {
      db.save([{name: 'Jon'}, {name: 'Helge'}], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function readObjs(user1, user2, done) {
      db.read([user1.id, user2.id], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function updateObjs(user1, user2, done) {
      user1.name = 'Bertin';
      user2.name = 'Erlend';
      db.save([user1, user2], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Bertin');
        assert.equal(users[1].name, 'Erlend');
        done();
      });
    }

    async.waterfall([createObjs, readObjs, updateObjs], done);
  });
});

describe('seraph#delete', function() {
  it('should delete an object', function(done) {
    function create(done) {
      db.save({ name: 'Neil', age: 61 }, function(err, user) {
        assert.ok(!err);
        assert.equal(user.name, 'Neil');
        assert.equal(user.age, 61);
        done(null, user);
      });
    }

    function del(user, done) {
      db.delete(user, function(err) {
         assert.ok(!err);
        db.read(user, function(err) {
          assert.ok(!!err);
          done();
        });
      });
    }

    async.waterfall([create, del], done);
  });

  it('should not delete node w/relations if not forced', function(done) {
    async.auto({
      n: function(cb) {
        db.save({}, cb);
      },
      m: function(cb) {
        db.save({}, cb);
      },
      r: ["n", "m", function(cb, res) {
        db.rel.create(res.n, "abscurs", res.m, cb);
      }],
      d: ["n", "r", function(cb, res) {
        db.delete(res.n, cb);
      }]
    }, function(err, res) {
      assert.ok(err);
      done();
    });
  });

  it('should delete node+relations if forced', function(done) {
    async.auto({
      n: function(cb) {
        db.save({potato:'mega'}, cb);
      },
      m: function(cb) {
        db.save({llol:'stuf'}, cb);
      },
      r: ["n", "m", function(cb, res) {
        db.rel.create(res.n, "abscurs", res.m, cb);
      }],
      d: ["n", "r", function(cb, res) {
        db.delete(res.n, true, cb);
      }]
    }, function(err, res) {
      assert.ok(!err, err);
      done();
    });
  });

  it('should delete node+relations if forced', function(done) {
    async.auto({
      n: function(cb) {
        db.save({potato:'mega'}, cb);
      },
      d: ["n", function(cb, res) {
        db.delete(res.n, true, function(err) {
          cb(err, res.n);
        });
      }]
    }, function(err, res) {
      assert.ok(!err, err);
      db.read(res.d, function(err, node) {
        assert(err.statusCode == 404);
        assert(!node);
        done();
      });
    });
  });

  it('should take an array of objects to delete', function(done) {
    function createObjs(done) {
      db.save([{name: 'Jon'}, {name: 'Helge'}], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function readObjs(user1, user2, done) {
      db.read([user1.id, user2.id], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function delObjs(user1, user2, done) {
      db.delete([user1.id, user2.id], function(err) {
        assert.ok(!err);
        db.read([user1.id, user2.id], function(err) {
          assert.ok(!!err);
          done();
        });
      });
    }

    async.waterfall([createObjs, readObjs, delObjs], done);
  });
});
<commit_msg>Added relationships in both directions to force delete test<commit_after>/* -*- Mode: Javascript; js-indent-level: 2 -*- */

var testDatabase = require('./util/database');
var db = require('../')(testDatabase.url);

var assert = require('assert');
var async = require('async');

describe('seraph#save, seraph#read', function() {
  it('should accept id of 0 on read', function(done) {
    db.read(0, function(err, data) {
      if (err)
        assert.equal(err.statusCode, 204); // neo4j gives 204 no content
      done();
    });
  });

  it('should accept id of 0 on save', function(done) {
    db.save({ id: 0, herp: "DERP" }, function(err, data) {
      if (err)
        assert.ok(err.statusCode); // not seraph error
      done();
    });
  });

  it('should handle alternative id property name', function(done) {
    function create(done) {
      db.save({ name: 'Jon', age: 23 }, function(err, user) {
        assert.ok(!err, err);
        assert.ok(typeof user.ponies !== 'undefined');
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);

        done(null, user.ponies);
      });
    }

    function read(userId, done) {
      db.read(userId, function(err, user) {
        assert.ok(!err, err);
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);
        done(null, user);
      });
    }

    var origId = db.options.id;
    db.options.id = "ponies";
    try {
      async.waterfall([create, read], function(err, res) {
        db.options.id = origId;
        done(err, res);
      });
    } catch (e) {
      db.options.id = origId;
      throw e;
    }
  });

  it('should be able to create an object and read it back', function(done) {
    function create(done) {
      db.save({ name: 'Jon', age: 23 }, function(err, user) {
        assert.ok(!err, err);
        assert.ok(typeof user.id !== 'undefined');
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);

        done(null, user.id);
      });
    }

    function read(userId, done) {
      db.read(userId, function(err, user) {
        assert.ok(!err, err);
        assert.equal(user.name, 'Jon');
        assert.equal(user.age, 23);
        done(null, user);
      });
    }

    async.waterfall([create, read], done);
  });

  it('should take an array of objects to save/read', function(done) {
    function createObjs(done) {
      db.save([{name: 'Jon'}, {name: 'Helge'}], function(err, users) {
        assert.ok(!err, err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function readObjs(user1, user2, done) {
      db.read([user1.id, user2.id], function(err, users) {
        assert.ok(!err, err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done();
      });
    }

    async.waterfall([createObjs, readObjs], done);
  });

  it('should handle an empty array of objects to save', function(done) {
    db.save([], done);
  });

  it('should not introduce id fields into the database', function(done) {
    db.save({pie: 'potato'}, function(err, thing) {
      db.read(thing, function(err, thingamajig) {
        db.save(thingamajig, function(err, thingamajiggy) {
          db.query('START n = node({id}) RETURN n.id? as thingamajiggle',
                   thingamajiggy, function(err, thingamajoggle) {
            assert.ok(thingamajoggle[0] === null);
            done();
          });
        });
      });
    });
  });
})

describe('seraph#update', function() {
  it('should perform an update on an object', function(done) {
    function create(done) {
      db.save({ name: 'Jan', age: 55 }, function(err, user) {
        assert.ok(!err);
        assert.equal(user.name, 'Jan');
        assert.equal(user.age, 55);
        done(null, user);
      });
    }

    function update(user, done) {
      user.name = 'Belinda';
      user.age = 26;
      var userId = user.id;
      db.save(user, function(err, user) {
        assert.ok(!err);
        assert.equal(userId, user.id);
        assert.equal(user.name, 'Belinda');
        assert.equal(user.age, 26);
        db.read(userId, function(err, user) {
          assert.ok(!err);
          assert.equal(userId, user.id);
          assert.equal(user.name, 'Belinda');
          assert.equal(user.age, 26);
          done(null, user);
        });
      });
    }

    async.waterfall([create, update], done);
  });

  it('should take an array of objects to save/read', function(done) {
    function createObjs(done) {
      db.save([{name: 'Jon'}, {name: 'Helge'}], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function readObjs(user1, user2, done) {
      db.read([user1.id, user2.id], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function updateObjs(user1, user2, done) {
      user1.name = 'Bertin';
      user2.name = 'Erlend';
      db.save([user1, user2], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Bertin');
        assert.equal(users[1].name, 'Erlend');
        done();
      });
    }

    async.waterfall([createObjs, readObjs, updateObjs], done);
  });
});

describe('seraph#delete', function() {
  it('should delete an object', function(done) {
    function create(done) {
      db.save({ name: 'Neil', age: 61 }, function(err, user) {
        assert.ok(!err);
        assert.equal(user.name, 'Neil');
        assert.equal(user.age, 61);
        done(null, user);
      });
    }

    function del(user, done) {
      db.delete(user, function(err) {
         assert.ok(!err);
        db.read(user, function(err) {
          assert.ok(!!err);
          done();
        });
      });
    }

    async.waterfall([create, del], done);
  });

  it('should not delete node w/relations if not forced', function(done) {
    async.auto({
      n: function(cb) {
        db.save({}, cb);
      },
      m: function(cb) {
        db.save({}, cb);
      },
      r: ["n", "m", function(cb, res) {
        db.rel.create(res.n, "abscurs", res.m, cb);
      }],
      d: ["n", "r", function(cb, res) {
        db.delete(res.n, cb);
      }]
    }, function(err, res) {
      assert.ok(err);
      done();
    });
  });

  it('should delete node+relations if forced', function(done) {
    async.auto({
      n: function(cb) {
        db.save({potato:'mega'}, cb);
      },
      m: function(cb) {
        db.save({llol:'stuf'}, cb);
      },
      r1: ["n", "m", function(cb, res) {
        db.rel.create(res.n, "abscurs", res.m, cb);
      }],
      r2: ["n", "m", function(cb, res) {
        db.rel.create(res.m, "something", res.n, cb);
      }],
      d: ["n", "r1", "r2", function(cb, res) {
        db.delete(res.n, true, cb);
      }]
    }, function(err, res) {
      assert.ok(!err, err);
      done();
    });
  });

  it('should delete node+relations if forced', function(done) {
    async.auto({
      n: function(cb) {
        db.save({potato:'mega'}, cb);
      },
      d: ["n", function(cb, res) {
        db.delete(res.n, true, function(err) {
          cb(err, res.n);
        });
      }]
    }, function(err, res) {
      assert.ok(!err, err);
      db.read(res.d, function(err, node) {
        assert(err.statusCode == 404);
        assert(!node);
        done();
      });
    });
  });

  it('should take an array of objects to delete', function(done) {
    function createObjs(done) {
      db.save([{name: 'Jon'}, {name: 'Helge'}], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function readObjs(user1, user2, done) {
      db.read([user1.id, user2.id], function(err, users) {
        assert.ok(!err);
        assert.equal(users[0].name, 'Jon');
        assert.equal(users[1].name, 'Helge');
        done(null, users[0], users[1]);
      });
    }

    function delObjs(user1, user2, done) {
      db.delete([user1.id, user2.id], function(err) {
        assert.ok(!err);
        db.read([user1.id, user2.id], function(err) {
          assert.ok(!!err);
          done();
        });
      });
    }

    async.waterfall([createObjs, readObjs, delObjs], done);
  });
});
<|endoftext|>


<commit_before>
console.log("Hi"); //Inicio, solo debug

//Variables a usar
var queue= [];

var badPlaces = [{x: 64.3, y: 128.6, width: 3, height: 4},{x: -257.2, y:192.9, width: 2, height: 1}];

var walls = [];

var globalState;

 var position = {
  x:0 , y:0
}

var queue= [];

//Determinar coordenadas de victoria
//var win = {x:y};

//Constructor de badObject

	//todas las funciones de animacion!
	(function($) {
		$(document).ready(function() {
				$('#Sprite')
					.sprite({fps: 9, no_of_frames: 3})
					.isDraggable()
					.activeOnClick()
					.active()
					.spStop();

				window.actions = {
					move_down: function() {
						$('#Sprite')
							.fps(10)
							.spState(1);
					},
					move_left: function() {
						$('#Sprite')
							.fps(10)
							.spState(2);
					},
					move_right: function() {
						$('#Sprite')
							.fps(10)
							.spState(3);
					},
					move_up: function() {
						$('#Sprite')
							.fps(10)
							.spState(4);
					},
					stop: function() {
						$('#Sprite')
							.spStop();
					},
				};
			});

		})(jQuery);

//Llenar el Queue
function addQueue(direction){
	queue.push(direction);
	console.log(queue);
}

//Borrar ultimo elemento del queue
function bBack(){
	queue.pop();
	console.log(queue);
}

//mover el background
function moveamount(x, y){
  position.x = position.x + x
  position.y = position.y + y
$('#background').css('background-position',position.x + 'px '+position.y+'px');

}

//ticker. Loop cada 800ms.
 function pressStart(){

	globalState = setInterval(function(){
	if (queue.length !==0){
		doMove = queue.shift();
		console.log(doMove);
		// Game over, sprite change, items, etc.
		switch(doMove) {
    case "N":
		actions.move_up();
        moveamount(0,64.3);
        break;
    case "S":
		actions.move_down();
        moveamount(0,-64.3);
        break;
	case "E":
		actions.move_right();
        moveamount(-64.3,0);
        break;
	case "O":
		actions.move_left();
        moveamount(64.3,0);
        break;
    default:
        console.log("Bad Arg") ;
}
	}
	else {
	//Se acabo el stack.
		//win!
		//Checar badPlaces var badPlaces = [{x: 1, y: 2, width: 3, height: 4},{x: 4, y:32, width: 2, height: 1}];
		console.log(position.x, position.y ) ;
		for(i=0; i<badPlaces.length; i++)
		{
			if(position.x= badPlaces[i].x)
				if(position.y= badPlaces[i].y)
					console.log("Valió Queque");

		}

		actions.stop();
		console.log("Stack empty");
		clearInterval(globalState);
		//Results
	}
	}, 800);
}
<commit_msg>cambie codigo de choque a la parte correcta<commit_after>
console.log("Hi"); //Inicio, solo debug

//Variables a usar
var queue= [];

var badPlaces = [{x: 64.3, y: 128.6, width: 3, height: 4},{x: -257.2, y:192.9, width: 2, height: 1}];

var walls = [];

var globalState;

 var position = {
  x:0 , y:0
}

var queue= [];

//Determinar coordenadas de victoria
//var win = {x:y};

//Constructor de badObject

	//todas las funciones de animacion!
	(function($) {
		$(document).ready(function() {
				$('#Sprite')
					.sprite({fps: 9, no_of_frames: 3})
					.isDraggable()
					.activeOnClick()
					.active()
					.spStop();

				window.actions = {
					move_down: function() {
						$('#Sprite')
							.fps(10)
							.spState(1);
					},
					move_left: function() {
						$('#Sprite')
							.fps(10)
							.spState(2);
					},
					move_right: function() {
						$('#Sprite')
							.fps(10)
							.spState(3);
					},
					move_up: function() {
						$('#Sprite')
							.fps(10)
							.spState(4);
					},
					stop: function() {
						$('#Sprite')
							.spStop();
					},
				};
			});

		})(jQuery);

//Llenar el Queue
function addQueue(direction){
	queue.push(direction);
	console.log(queue);
}

//Borrar ultimo elemento del queue
function bBack(){
	queue.pop();
	console.log(queue);
}

//mover el background
function moveamount(x, y){
  position.x = position.x + x
  position.y = position.y + y
$('#background').css('background-position',position.x + 'px '+position.y+'px');

}

//ticker. Loop cada 800ms.
 function pressStart(){

	globalState = setInterval(function(){
	if (queue.length !==0){
		doMove = queue.shift();
		console.log(doMove);
		// Game over, sprite change, items, etc.
		switch(doMove) {
			case "N":
				actions.move_up();
				moveamount(0,64.3);
				break;
			case "S":
				actions.move_down();
				moveamount(0,-64.3);
				break;
			case "E":
				actions.move_right();
				moveamount(-64.3,0);
				break;
			case "O":
				actions.move_left();
				moveamount(64.3,0);
				break;
			default:
				console.log("Bad Arg") ;
			}

			//Checar badPlaces var badPlaces = [{x: 1, y: 2, width: 3, height: 4},{x: 4, y:32, width: 2, height: 1}];
			console.log(position.x, position.y ) ;
		for(i=0; i<badPlaces.length; i++){
			if(position.x == badPlaces[i].x){
				if(position.y == badPlaces[i].y){
					console.log("Valió Queque");
					queue = [];
				}
			}
		}
	} else {
		//Se acabo el stack.
		//win!
				actions.stop();
		console.log("Stack empty");
		clearInterval(globalState);
		//Results
	}
	}, 800);
}
<|endoftext|>


<commit_before>/* @flow */
import React from 'react';
import { Platform } from 'react-native';
import { TabNavigator, TabBarBottom } from 'react-navigation';

import type { TabNavigationOptionsPropsType } from '../types';
import tabsOptions from '../styles/tabs';
import HomeTab from './HomeTab';
import StreamTabs from './StreamTabs';
import ConversationsContainer from '../conversations/ConversationsContainer';
import SettingsCard from '../settings/SettingsCard';
import { IconHome, IconStream, IconSettings } from '../common/Icons';
import IconUnreadConversations from '../nav/IconUnreadConversations';

export default TabNavigator(
  {
    home: {
      screen: HomeTab,
      navigationOptions: {
        tabBarLabel: 'Home',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconHome size={24} color={props.tintColor} />
        ),
      },
    },
    streams: {
      screen: StreamTabs,
      navigationOptions: {
        tabBarLabel: 'Streams',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconStream size={24} color={props.tintColor} />
        ),
      },
    },
    conversations: {
      screen: ConversationsContainer,
      navigationOptions: {
        tabBarLabel: 'Conversations',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconUnreadConversations color={props.tintColor} />
        ),
      },
    },
    settings: {
      screen: SettingsCard,
      navigationOptions: {
        tabBarLabel: 'Settings',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconSettings size={24} color={props.tintColor} />
        ),
      },
    },
  },
  tabsOptions({
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    showLabel: !!Platform.isPad,
    showIcon: true,
  }),
);
<commit_msg>fix: Disable Android Back Button in Tabs<commit_after>/* @flow */
import React from 'react';
import { Platform } from 'react-native';
import { TabNavigator, TabBarBottom } from 'react-navigation';

import type { TabNavigationOptionsPropsType } from '../types';
import tabsOptions from '../styles/tabs';
import HomeTab from './HomeTab';
import StreamTabs from './StreamTabs';
import ConversationsContainer from '../conversations/ConversationsContainer';
import SettingsCard from '../settings/SettingsCard';
import { IconHome, IconStream, IconSettings } from '../common/Icons';
import IconUnreadConversations from '../nav/IconUnreadConversations';

export default TabNavigator(
  {
    home: {
      screen: HomeTab,
      navigationOptions: {
        tabBarLabel: 'Home',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconHome size={24} color={props.tintColor} />
        ),
      },
    },
    streams: {
      screen: StreamTabs,
      navigationOptions: {
        tabBarLabel: 'Streams',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconStream size={24} color={props.tintColor} />
        ),
      },
    },
    conversations: {
      screen: ConversationsContainer,
      navigationOptions: {
        tabBarLabel: 'Conversations',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconUnreadConversations color={props.tintColor} />
        ),
      },
    },
    settings: {
      screen: SettingsCard,
      navigationOptions: {
        tabBarLabel: 'Settings',
        tabBarIcon: (props: TabNavigationOptionsPropsType) => (
          <IconSettings size={24} color={props.tintColor} />
        ),
      },
    },
  },
  {
    ...tabsOptions({
      tabBarComponent: TabBarBottom,
      tabBarPosition: 'bottom',
      showLabel: !!Platform.isPad,
      showIcon: true,
    }),
    backBehavior: 'none',
  },
);
<|endoftext|>


<commit_before>+ function() {
    function each(o, cb) {
        for (var p in o) {
            if (o.hasOwnProperty(p)) {
                cb(o[p], p, o);
            }
        }
    }

    function find(ar, cb) {
        if (ar.length) {
            for (var i = 0; i < ar.length; i++) {
                if (cb(ar[i])) {
                    return ar[i];
                }
            }
        } else {
            for (var p in ar) {
                if (ar.hasOwnProperty(p) && cb(ar[p])) {
                    return ar[p];
                }
            }
        }
    }

    function first(o) {
        for (var p in o) {
            if (o.hasOwnProperty(p)) {
                return o[p];
            }
        }
    }

    function length(o) {
        var length = 0;
        for (var p in o) {
            if (o.hasOwnProperty(p)) {
                length++;
            }
        }
        return length;
    }

    function prepend(parent, el) {
        if (parent.children.length) {
            parent.insertBefore(el, parent.children[0]);
        } else {
            parent.appendChild(el);
        }
    }

    L.Control.IconLayers = L.Control.extend({
        includes: L.Mixin.Events,
        _getActiveLayer: function() {
            if (this._activeLayerId) {
                return this._layers[this._activeLayerId];
            } else if (length(this._layers)) {
                return first(this._layers);
            } else {
                return null;
            }
        },
        _getPreviousLayer: function() {
            var activeLayer = this._getActiveLayer();
            if (!activeLayer) {
                return null;
            } else if (this._previousLayerId) {
                return this._layers[this._previousLayerId];
            } else {
                return find(this._layers, function(l) {
                    return l.id !== activeLayer.id;
                }.bind(this)) || null;
            }
        },
        _getInactiveLayers: function() {
            var ar = [];
            var activeLayerId = this._getActiveLayer() ? this._getActiveLayer().id : null;
            var previousLayerId = this._getPreviousLayer() ? this._getPreviousLayer().id : null;
            each(this._layers, function(l) {
                if ((l.id !== activeLayerId) && (l.id !== previousLayerId)) {
                    ar.push(l);
                }
            });
            return ar;
        },
        _arrangeLayers: function() {
            var behaviors = {};

            behaviors['previous'] = function() {
                var activeLayer = this._getActiveLayer();
                var previousLayer = this._getPreviousLayer();
                if (previousLayer) {
                    return [previousLayer, activeLayer].concat(this._getInactiveLayers());
                } else if (activeLayer) {
                    return [activeLayer].concat(this._getInactiveLayers());
                } else {
                    return null;
                }
            };

            return behaviors[this.options.behavior].apply(this, arguments);
        },
        _getLayerCellByLayerId: function(id) {
            var els = this._container.getElementsByClassName('leaflet-iconLayers-layerCell');
            for (var i = 0; i < els.length; i++) {
                if (els[i].getAttribute('data-layerid') == id) {
                    return els[i];
                }
            }
        },
        _createLayerElement: function(layerObj) {
            var el = L.DomUtil.create('div', 'leaflet-iconLayers-layer');
            if (layerObj.title) {
                var titleContainerEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerTitleContainer');
                var titleEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerTitle');
                var checkIconEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerCheckIcon');
                titleEl.innerHTML = layerObj.title;
                titleContainerEl.appendChild(titleEl);
                el.appendChild(titleContainerEl);
                el.appendChild(checkIconEl);
            }
            if (layerObj.icon) {
                el.setAttribute('style', "background-image: url('" + layerObj.icon + "')");
            }
            return el;
        },
        _createLayerElements: function() {
            var currentRow, layerCell;
            var layers = this._arrangeLayers();
            var activeLayerId = this._getActiveLayer().id;

            for (var i = 0; i < layers.length; i++) {
                if (i % this.options.maxLayersInRow === 0) {
                    currentRow = L.DomUtil.create('div', 'leaflet-iconLayers-layersRow');
                    if (this.options.position.indexOf('bottom') === -1) {
                        this._container.appendChild(currentRow);
                    } else {
                        prepend(this._container, currentRow);
                    }
                }
                layerCell = L.DomUtil.create('div', 'leaflet-iconLayers-layerCell');
                layerCell.setAttribute('data-layerid', layers[i].id);
                if (i !== 0) {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_hidden');
                }
                if (layers[i].id === activeLayerId) {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_active');
                }
                if (this._expandDirection === 'left') {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_expandLeft');
                } else {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_expandRight');
                }
                layerCell.appendChild(this._createLayerElement(layers[i]));

                if (this.options.position.indexOf('right') === -1) {
                    currentRow.appendChild(layerCell);
                } else {
                    prepend(currentRow, layerCell);
                }
            }
        },
        _attachEvents: function() {
            each(this._layers, function(l) {
                var e = this._getLayerCellByLayerId(l.id);
                if (e) {
                    e.addEventListener('click', function(e) {
                        e.stopPropagation();
                        this.setActiveLayer(l.layer);
                        this.expand();
                    }.bind(this));
                }
            }.bind(this));
            var layersRowCollection = this._container.getElementsByClassName('leaflet-iconLayers-layersRow');
            for (var i = 0; i < layersRowCollection.length; i++) {
                var el = layersRowCollection[i];
                el.addEventListener('mouseenter', function(e) {
                    e.stopPropagation();
                    this.expand();
                }.bind(this));
                el.addEventListener('mouseleave', function(e) {
                    e.stopPropagation();
                    this.collapse();
                }.bind(this));
                el.addEventListener('mousemove', function(e) {
                    e.stopPropagation();
                });
            }
        },
        _render: function() {
            this._container.innerHTML = '';
            this._createLayerElements();
            this._attachEvents();
        },
        options: {
            position: 'bottomleft', // one of expanding directions depends on this
            behavior: 'previous', // may be 'previous', 'expanded' or 'first'
            expand: 'horizontal', // or 'vertical'
            autoZIndex: true, // from L.Control.Layers
            maxLayersInRow: 5
        },
        initialize: function(layers, options) {
            L.setOptions(this, options);
            this._expandDirection = (this.options.position.indexOf('left') != -1) ? 'right' : 'left';
            this.setLayers(layers);
        },
        onAdd: function(map) {
            this._container = L.DomUtil.create('div', 'leaflet-iconLayers');
            L.DomUtil.addClass(this._container, 'leaflet-iconLayers_' + this.options.position);
            this._render();
            return this._container;
        },
        setLayers: function(layers) {
            this._layers = {};
            layers.map(function(layer) {
                var id = L.stamp(layer.layer)
                this._layers[id] = L.extend(layer, {
                    id: id
                });
            }.bind(this));
            this._container && this._render();
        },
        setActiveLayer: function(layer) {
            var l = layer && this._layers[L.stamp(layer)];
            if (!l || l.id === this._activeLayerId) {
                return;
            }
            this._previousLayerId = this._activeLayerId;
            this._activeLayerId = l.id;
            this._container && this._render();
            this.fire('activelayerchange', {
                layer: layer
            });
        },
        expand: function() {
            this._arrangeLayers().slice(1).map(function(l) {
                var el = this._getLayerCellByLayerId(l.id);
                L.DomUtil.removeClass(el, 'leaflet-iconLayers-layerCell_hidden');
            }.bind(this));
        },
        collapse: function() {
            this._arrangeLayers().slice(1).map(function(l) {
                var el = this._getLayerCellByLayerId(l.id);
                L.DomUtil.addClass(el, 'leaflet-iconLayers-layerCell_hidden');
            }.bind(this));
        }
    });
}();<commit_msg>fix setLayers() bugs<commit_after>+ function() {
    function each(o, cb) {
        for (var p in o) {
            if (o.hasOwnProperty(p)) {
                cb(o[p], p, o);
            }
        }
    }

    function find(ar, cb) {
        if (ar.length) {
            for (var i = 0; i < ar.length; i++) {
                if (cb(ar[i])) {
                    return ar[i];
                }
            }
        } else {
            for (var p in ar) {
                if (ar.hasOwnProperty(p) && cb(ar[p])) {
                    return ar[p];
                }
            }
        }
    }

    function first(o) {
        for (var p in o) {
            if (o.hasOwnProperty(p)) {
                return o[p];
            }
        }
    }

    function length(o) {
        var length = 0;
        for (var p in o) {
            if (o.hasOwnProperty(p)) {
                length++;
            }
        }
        return length;
    }

    function prepend(parent, el) {
        if (parent.children.length) {
            parent.insertBefore(el, parent.children[0]);
        } else {
            parent.appendChild(el);
        }
    }

    L.Control.IconLayers = L.Control.extend({
        includes: L.Mixin.Events,
        _getActiveLayer: function() {
            if (this._activeLayerId) {
                return this._layers[this._activeLayerId];
            } else if (length(this._layers)) {
                return first(this._layers);
            } else {
                return null;
            }
        },
        _getPreviousLayer: function() {
            var activeLayer = this._getActiveLayer();
            if (!activeLayer) {
                return null;
            } else if (this._previousLayerId) {
                return this._layers[this._previousLayerId];
            } else {
                return find(this._layers, function(l) {
                    return l.id !== activeLayer.id;
                }.bind(this)) || null;
            }
        },
        _getInactiveLayers: function() {
            var ar = [];
            var activeLayerId = this._getActiveLayer() ? this._getActiveLayer().id : null;
            var previousLayerId = this._getPreviousLayer() ? this._getPreviousLayer().id : null;
            each(this._layers, function(l) {
                if ((l.id !== activeLayerId) && (l.id !== previousLayerId)) {
                    ar.push(l);
                }
            });
            return ar;
        },
        _arrangeLayers: function() {
            var behaviors = {};

            behaviors['previous'] = function() {
                var layers = this._getInactiveLayers();
                this._getActiveLayer() && layers.unshift(this._getActiveLayer());
                this._getPreviousLayer() && layers.unshift(this._getPreviousLayer());
                return layers;
            };

            return behaviors[this.options.behavior].apply(this, arguments);
        },
        _getLayerCellByLayerId: function(id) {
            var els = this._container.getElementsByClassName('leaflet-iconLayers-layerCell');
            for (var i = 0; i < els.length; i++) {
                if (els[i].getAttribute('data-layerid') == id) {
                    return els[i];
                }
            }
        },
        _createLayerElement: function(layerObj) {
            var el = L.DomUtil.create('div', 'leaflet-iconLayers-layer');
            if (layerObj.title) {
                var titleContainerEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerTitleContainer');
                var titleEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerTitle');
                var checkIconEl = L.DomUtil.create('div', 'leaflet-iconLayers-layerCheckIcon');
                titleEl.innerHTML = layerObj.title;
                titleContainerEl.appendChild(titleEl);
                el.appendChild(titleContainerEl);
                el.appendChild(checkIconEl);
            }
            if (layerObj.icon) {
                el.setAttribute('style', "background-image: url('" + layerObj.icon + "')");
            }
            return el;
        },
        _createLayerElements: function() {
            var currentRow, layerCell;
            var layers = this._arrangeLayers();
            var activeLayerId = this._getActiveLayer() && this._getActiveLayer().id;

            for (var i = 0; i < layers.length; i++) {
                if (i % this.options.maxLayersInRow === 0) {
                    currentRow = L.DomUtil.create('div', 'leaflet-iconLayers-layersRow');
                    if (this.options.position.indexOf('bottom') === -1) {
                        this._container.appendChild(currentRow);
                    } else {
                        prepend(this._container, currentRow);
                    }
                }
                layerCell = L.DomUtil.create('div', 'leaflet-iconLayers-layerCell');
                layerCell.setAttribute('data-layerid', layers[i].id);
                if (i !== 0) {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_hidden');
                }
                if (layers[i].id === activeLayerId) {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_active');
                }
                if (this._expandDirection === 'left') {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_expandLeft');
                } else {
                    L.DomUtil.addClass(layerCell, 'leaflet-iconLayers-layerCell_expandRight');
                }
                layerCell.appendChild(this._createLayerElement(layers[i]));

                if (this.options.position.indexOf('right') === -1) {
                    currentRow.appendChild(layerCell);
                } else {
                    prepend(currentRow, layerCell);
                }
            }
        },
        _attachEvents: function() {
            each(this._layers, function(l) {
                var e = this._getLayerCellByLayerId(l.id);
                if (e) {
                    e.addEventListener('click', function(e) {
                        e.stopPropagation();
                        this.setActiveLayer(l.layer);
                        this.expand();
                    }.bind(this));
                }
            }.bind(this));
            var layersRowCollection = this._container.getElementsByClassName('leaflet-iconLayers-layersRow');
            for (var i = 0; i < layersRowCollection.length; i++) {
                var el = layersRowCollection[i];
                el.addEventListener('mouseenter', function(e) {
                    e.stopPropagation();
                    this.expand();
                }.bind(this));
                el.addEventListener('mouseleave', function(e) {
                    e.stopPropagation();
                    this.collapse();
                }.bind(this));
                el.addEventListener('mousemove', function(e) {
                    e.stopPropagation();
                });
            }
        },
        _render: function() {
            this._container.innerHTML = '';
            this._createLayerElements();
            this._attachEvents();
        },
        options: {
            position: 'bottomleft', // one of expanding directions depends on this
            behavior: 'previous', // may be 'previous', 'expanded' or 'first'
            expand: 'horizontal', // or 'vertical'
            autoZIndex: true, // from L.Control.Layers
            maxLayersInRow: 5
        },
        initialize: function(layers, options) {
            L.setOptions(this, options);
            this._expandDirection = (this.options.position.indexOf('left') != -1) ? 'right' : 'left';
            this.setLayers(layers);
        },
        onAdd: function(map) {
            this._container = L.DomUtil.create('div', 'leaflet-iconLayers');
            L.DomUtil.addClass(this._container, 'leaflet-iconLayers_' + this.options.position);
            this._render();
            return this._container;
        },
        setLayers: function(layers) {
            this._layers = {};
            layers.map(function(layer) {
                var id = L.stamp(layer.layer)
                this._layers[id] = L.extend(layer, {
                    id: id
                });
            }.bind(this));
            this._container && this._render();
        },
        setActiveLayer: function(layer) {
            var l = layer && this._layers[L.stamp(layer)];
            if (!l || l.id === this._activeLayerId) {
                return;
            }
            this._previousLayerId = this._activeLayerId;
            this._activeLayerId = l.id;
            this._container && this._render();
            this.fire('activelayerchange', {
                layer: layer
            });
        },
        expand: function() {
            this._arrangeLayers().slice(1).map(function(l) {
                var el = this._getLayerCellByLayerId(l.id);
                L.DomUtil.removeClass(el, 'leaflet-iconLayers-layerCell_hidden');
            }.bind(this));
        },
        collapse: function() {
            this._arrangeLayers().slice(1).map(function(l) {
                var el = this._getLayerCellByLayerId(l.id);
                L.DomUtil.addClass(el, 'leaflet-iconLayers-layerCell_hidden');
            }.bind(this));
        }
    });
}();<|endoftext|>


<commit_before>/**
 * @typedef {import('mdast').Root} Root
 * @typedef {import('vfile').VFile} VFile
 * @typedef {import('type-fest').PackageJson} PackageJson
 * @typedef {import('../index.js').Options} Options
 *
 * @typedef {import('@babel/core').BabelFileResult} FileResult
 * @typedef {import('@babel/core').PluginPass} PluginPass
 * @typedef {import('@babel/types').ImportDeclaration} ImportDeclaration
 * @typedef {import('@babel/types').CallExpression} CallExpression
 * @typedef {import('@babel/types').StringLiteral} StringLiteral
 *
 * @typedef Log
 * @property {number|null} start
 * @property {number|null} end
 * @property {string|undefined} language
 * @property {string[]} values
 *
 * @typedef Reference
 * @property {number|null} start
 * @property {number|null} end
 * @property {string} quote
 */

import {resolve} from 'import-meta-resolve'
import babel from '@babel/core'

/** @param {{tree: Root, file: VFile, options: Options, pkg: PackageJson, pkgRoot: string, main: string|undefined, name: string|undefined, id: string, exampleFileUrl: string, example: string, exampleInstrumented?: string, logs?: Log[], mainReferences?: Reference[]}} ctx */
export async function instrument(ctx) {
  /** @type {StringLiteral[]} */
  const nodes = []
  /** @type {Log[]} */
  const logs = []
  /** @type {Reference[]} */
  const mainReferences = []
  /** @type {FileResult|null} */
  let result

  try {
    result = await babel.transformAsync(ctx.example, {
      plugins: [addIdToConsoleLog],
      cwd: ctx.file.cwd,
      filename: ctx.exampleFileUrl,
      caller: {name: 'remark-usage'},
      sourceType: 'unambiguous'
    })
  } catch (error) {
    throw new Error('Could not parse example: ' + error)
  }

  const promises = nodes.map(async (node) => {
    try {
      const resolved = await resolve(node.value, ctx.exampleFileUrl)

      if (resolved === ctx.main) {
        // Babel always adds raw, but just to be sure.
        /* c8 ignore next */
        const raw = String((node && node.extra && node.extra.raw) || "'")

        mainReferences.push({
          start: node.start,
          end: node.end,
          quote: raw.charAt(0)
        })
      }
    } catch {}
  })

  await Promise.allSettled(promises)

  ctx.exampleInstrumented = (result && result.code) || ''
  ctx.logs = logs
  ctx.mainReferences = mainReferences

  function addIdToConsoleLog() {
    const t = babel.types
    let index = -1

    /** @type {PluginPass} */
    return {
      visitor: {
        /**
         * @param {import('@babel/core').NodePath<ImportDeclaration>} path
         */
        ImportDeclaration(path) {
          nodes.push(path.node.source)
        },
        /**
         * @param {import('@babel/core').NodePath<CallExpression>} path
         */
        CallExpression(path) {
          const callee = path.get('callee')
          const head = path.get('arguments.0')

          if (
            callee.isIdentifier({name: 'require'}) &&
            !Array.isArray(head) &&
            head.isStringLiteral()
          ) {
            nodes.push(head.node)
          }

          if (callee.matchesPattern('console.log')) {
            instrumentConsoleLog(path)
          }
        }
      }
    }

    /**
     * @param {import('@babel/core').NodePath<CallExpression>} path
     */
    function instrumentConsoleLog(path) {
      const node = path.node
      const args = [...node.arguments]
      const head = args[0]
      /** @type {string|undefined} */
      let language

      index++

      if (head && head.type === 'StringLiteral' && args.length > 1) {
        language = head.value
        args.shift()
      }

      logs[index] = {
        start: node.start,
        end: node.end,
        language,
        values: []
      }

      node.arguments = [
        t.stringLiteral('<' + ctx.id + '-' + index + '>'),
        ...args,
        t.stringLiteral('</' + ctx.id + '>')
      ]
    }
  }
}
<commit_msg>Fix file path in babel error<commit_after>/**
 * @typedef {import('mdast').Root} Root
 * @typedef {import('vfile').VFile} VFile
 * @typedef {import('type-fest').PackageJson} PackageJson
 * @typedef {import('../index.js').Options} Options
 *
 * @typedef {import('@babel/core').BabelFileResult} FileResult
 * @typedef {import('@babel/core').PluginPass} PluginPass
 * @typedef {import('@babel/types').ImportDeclaration} ImportDeclaration
 * @typedef {import('@babel/types').CallExpression} CallExpression
 * @typedef {import('@babel/types').StringLiteral} StringLiteral
 *
 * @typedef Log
 * @property {number|null} start
 * @property {number|null} end
 * @property {string|undefined} language
 * @property {string[]} values
 *
 * @typedef Reference
 * @property {number|null} start
 * @property {number|null} end
 * @property {string} quote
 */

import url from 'url'
import {resolve} from 'import-meta-resolve'
import babel from '@babel/core'

/** @param {{tree: Root, file: VFile, options: Options, pkg: PackageJson, pkgRoot: string, main: string|undefined, name: string|undefined, id: string, exampleFileUrl: string, example: string, exampleInstrumented?: string, logs?: Log[], mainReferences?: Reference[]}} ctx */
export async function instrument(ctx) {
  /** @type {StringLiteral[]} */
  const nodes = []
  /** @type {Log[]} */
  const logs = []
  /** @type {Reference[]} */
  const mainReferences = []
  /** @type {FileResult|null} */
  let result

  try {
    result = await babel.transformAsync(ctx.example, {
      plugins: [addIdToConsoleLog],
      cwd: ctx.file.cwd,
      filename: url.fileURLToPath(ctx.exampleFileUrl),
      caller: {name: 'remark-usage'},
      sourceType: 'unambiguous'
    })
  } catch (error) {
    throw new Error('Could not parse example: ' + error)
  }

  const promises = nodes.map(async (node) => {
    try {
      const resolved = await resolve(node.value, ctx.exampleFileUrl)

      if (resolved === ctx.main) {
        // Babel always adds raw, but just to be sure.
        /* c8 ignore next */
        const raw = String((node && node.extra && node.extra.raw) || "'")

        mainReferences.push({
          start: node.start,
          end: node.end,
          quote: raw.charAt(0)
        })
      }
    } catch {}
  })

  await Promise.allSettled(promises)

  ctx.exampleInstrumented = (result && result.code) || ''
  ctx.logs = logs
  ctx.mainReferences = mainReferences

  function addIdToConsoleLog() {
    const t = babel.types
    let index = -1

    /** @type {PluginPass} */
    return {
      visitor: {
        /**
         * @param {import('@babel/core').NodePath<ImportDeclaration>} path
         */
        ImportDeclaration(path) {
          nodes.push(path.node.source)
        },
        /**
         * @param {import('@babel/core').NodePath<CallExpression>} path
         */
        CallExpression(path) {
          const callee = path.get('callee')
          const head = path.get('arguments.0')

          if (
            callee.isIdentifier({name: 'require'}) &&
            !Array.isArray(head) &&
            head.isStringLiteral()
          ) {
            nodes.push(head.node)
          }

          if (callee.matchesPattern('console.log')) {
            instrumentConsoleLog(path)
          }
        }
      }
    }

    /**
     * @param {import('@babel/core').NodePath<CallExpression>} path
     */
    function instrumentConsoleLog(path) {
      const node = path.node
      const args = [...node.arguments]
      const head = args[0]
      /** @type {string|undefined} */
      let language

      index++

      if (head && head.type === 'StringLiteral' && args.length > 1) {
        language = head.value
        args.shift()
      }

      logs[index] = {
        start: node.start,
        end: node.end,
        language,
        values: []
      }

      node.arguments = [
        t.stringLiteral('<' + ctx.id + '-' + index + '>'),
        ...args,
        t.stringLiteral('</' + ctx.id + '>')
      ]
    }
  }
}
<|endoftext|>