<commit_before>import should from 'should/as-function';
import Promise from 'bluebird';
import _ from 'lodash';
import Syncano from '../../src/syncano';
import {suffix, credentials} from './utils';
import {ValidationError} from '../../src/errors';

describe('Instance', function() {
  this.timeout(15000);

  const connection = Syncano(credentials);
  const instanceName = suffix.get('name');

  afterEach(function(done) {
    connection.Instance
      .please()
      .delete({name: instanceName})
      .then(() => done())
      .catch(() => done());
  });

  it('should be validated', function() {
    should(connection.Instance().save()).be.rejectedWith(ValidationError);
  });

  it('should be able to save via model instance', function() {
    const data = {
      name: instanceName,
      description: suffix.get('description')
    };

    return connection.Instance(data).save()
      .then((instance) => {
        should(instance).be.a.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal(data.description);
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
  });

  it('should be able to update via model instance', function() {
    const data = {
      name: instanceName,
      description: suffix.get('description')
    };

    return connection.Instance(data).save()
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal(data.description);

        instance.description = 'new description';
        return instance.save();
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal('new description');
      });
  });

  it('should be able to delete via model instance', function() {
    const data = {
      name: instanceName,
      description: suffix.get('description')
    };

    return connection.Instance(data).save()
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal(data.description);

        return instance.delete();
      });
  });

  describe('#please()', function() {

    it('should be able to list instances', function() {
      return connection.Instance.please().list().then((instances) => {
        should(instances).be.an.Array();
      });
    });

    it('should be able to create an instance', function() {
      return connection.Instance.please().create({name: instanceName}).then((instance) => {
        should(instance).be.a.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String();
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
    });

    it('should be able to get an instance', function() {
      return connection.Instance.please().create({name: instanceName})
        .then((instance) => {
          should(instance).be.an.Object();
          should(instance).have.property('name').which.is.String().equal(instanceName);
          return instance;
        })
        .then(() => {
          return connection
            .Instance
            .please()
            .get({name: instanceName})
            .request();
        })
        .then((instance) => {
          should(instance).be.an.Object();
          should(instance).have.property('name').which.is.String().equal(instanceName);
          should(instance).have.property('description').which.is.String();
          should(instance).have.property('created_at').which.is.String();
          should(instance).have.property('updated_at').which.is.String();
          should(instance).have.property('links').which.is.Object();
          should(instance).have.property('owner').which.is.Object();
          should(instance).have.property('metadata').which.is.Object();
        });
    });

    it('should be able to delete an instance', function() {
      return connection.Instance.please().create({name: instanceName})
        .then((instance) => {
          should(instance).be.an.Object();
          should(instance).have.property('name').which.is.String().equal(instanceName);
          return instance;
        })
        .then(() => {
          return connection
            .Instance
            .please()
            .delete({name: instanceName})
            .request();
        });
    });

    it('should be able to get or create instance (CREATE)', function() {
      return connection.Instance.please().getOrCreate({name: instanceName}, {description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
    });

    it('should be able to get or create instance (GET)', function() {
      return connection.Instance.please().create({name: instanceName, description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');

        return connection.Instance.please().getOrCreate({name: instanceName}, {description: 'newTest'});
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');
      });
    });

    it('should be able to update an instance', function() {
      return connection.Instance.please().create({name: instanceName, description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');

        return connection.Instance.please().update({name: instance.name}, {description: 'newTest'});
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('newTest');
      });
    });

    it('should be able to update or create instance (UPDATE)', function() {
      return connection.Instance.please().create({name: instanceName, description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');

        return connection.Instance.please().updateOrCreate({name: instance.name}, {description: 'newTest'});
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('newTest');
      });
    });

    it('should be able to update or create instance (CREATE)', function() {
      let properties = {name: instanceName};
      let object = {description: 'updateTest'};
      let defaults = {
          description: 'createTest',
          metadata: {'test': 1}
      };

      return connection.Instance.please().updateOrCreate(properties, object, defaults).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('createTest');
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
    });

    it('should be able to get first instance (SUCCESS)', function() {
      const names = [
        `${instanceName}_1`,
        `${instanceName}_2`
      ];

      return Promise
        .all(_.map(names, (name) => connection.Instance.please().create({name})))
        .then(() => {
          return connection.Instance.please().first();
        })
        .then((instance) => {
          should(instance).be.an.Object();
        })
        .finally(() => {
          return Promise.all(_.map(names, (name) => connection.Instance.please().delete({name})));
        });
    });

    it('should be able to change page size', function() {
      const names = [
        `${instanceName}_1`,
        `${instanceName}_2`
      ];

      return Promise
        .all(_.map(names, (name) => connection.Instance.please().create({name: name})))
        .then((instances) => {
          should(instances).be.an.Array().with.length(2);
          return connection.Instance.please().pageSize(1);
        })
        .then((instances) => {
          should(instances).be.an.Array().with.length(1);
        })
        .finally(() => {
          return Promise.all(_.map(names, (name) => connection.Instance.please().delete({name: name})));
        });
    });

    it('should be able to change ordering', function() {
      const names = [
        `${instanceName}_1`,
        `${instanceName}_2`
      ];
      let ascInstances = null;

      return Promise
        .all(_.map(names, (name) => connection.Instance.please().create({name: name})))
        .then((instances) => {
          should(instances).be.an.Array().with.length(2);
          return connection.Instance.please().ordering('asc');
        })
        .then((instances) => {
          should(instances).be.an.Array().with.length(2);
          ascInstances = instances;
          return connection.Instance.please().ordering('desc');
        }).then((descInstances) => {
          const ascNames = _.map(ascInstances, 'name');
          const descNames = _.map(descInstances, 'name');
          descNames.reverse();

          should(descInstances).be.an.Array().with.length(2);
          _.forEach(ascNames, (ascName, index) => {
            should(ascName).be.equal(descNames[index]);
          });
        })
        .finally(() => {
          return Promise.all(_.map(names, (name) => connection.Instance.please().delete({name: name})));
        });
    });

    it('should be able to get raw data', function() {
      return connection.Instance.please().list().raw().then((response) => {
        should(response).be.a.Object();
        should(response).have.property('objects').which.is.Array();
        should(response).have.property('next').which.is.null();
        should(response).have.property('prev').which.is.null();
      });
    });

  });

});
<commit_msg>[jsdoc] test fix<commit_after>import should from 'should/as-function';
import Promise from 'bluebird';
import _ from 'lodash';
import Syncano from '../../src/syncano';
import {suffix, credentials} from './utils';
import {ValidationError} from '../../src/errors';

describe('Instance', function() {
  this.timeout(15000);

  const connection = Syncano(credentials);
  const instanceName = suffix.get('name');

  afterEach(function(done) {
    connection.Instance
      .please()
      .delete({name: instanceName})
      .then(() => done())
      .catch(() => done());
  });

  it('should be validated', function() {
    should(connection.Instance().save()).be.rejectedWith(ValidationError);
  });

  it('should be able to save via model instance', function() {
    const data = {
      name: instanceName,
      description: suffix.get('description')
    };

    return connection.Instance(data).save()
      .then((instance) => {
        should(instance).be.a.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal(data.description);
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
  });

  it('should be able to update via model instance', function() {
    const data = {
      name: instanceName,
      description: suffix.get('description')
    };

    return connection.Instance(data).save()
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal(data.description);

        instance.description = 'new description';
        return instance.save();
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal('new description');
      });
  });

  it('should be able to delete via model instance', function() {
    const data = {
      name: instanceName,
      description: suffix.get('description')
    };

    return connection.Instance(data).save()
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(data.name);
        should(instance).have.property('description').which.is.String().equal(data.description);

        return instance.delete();
      });
  });

  describe('#please()', function() {

    it('should be able to list instances', function() {
      return connection.Instance.please().list().then((instances) => {
        should(instances).be.an.Array();
      });
    });

    it('should be able to create an instance', function() {
      return connection.Instance.please().create({name: instanceName}).then((instance) => {
        should(instance).be.a.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String();
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
    });

    it('should be able to get an instance', function() {
      return connection.Instance.please().create({name: instanceName})
        .then((instance) => {
          should(instance).be.an.Object();
          should(instance).have.property('name').which.is.String().equal(instanceName);
          return instance;
        })
        .then(() => {
          return connection
            .Instance
            .please()
            .get({name: instanceName})
            .request();
        })
        .then((instance) => {
          should(instance).be.an.Object();
          should(instance).have.property('name').which.is.String().equal(instanceName);
          should(instance).have.property('description').which.is.String();
          should(instance).have.property('created_at').which.is.String();
          should(instance).have.property('updated_at').which.is.String();
          should(instance).have.property('links').which.is.Object();
          should(instance).have.property('owner').which.is.Object();
          should(instance).have.property('metadata').which.is.Object();
        });
    });

    it('should be able to delete an instance', function() {
      return connection.Instance.please().create({name: instanceName})
        .then((instance) => {
          should(instance).be.an.Object();
          should(instance).have.property('name').which.is.String().equal(instanceName);
          return instance;
        })
        .then(() => {
          return connection
            .Instance
            .please()
            .delete({name: instanceName})
            .request();
        });
    });

    it('should be able to get or create instance (CREATE)', function() {
      return connection.Instance.please().getOrCreate({name: instanceName}, {description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
    });

    it('should be able to get or create instance (GET)', function() {
      return connection.Instance.please().create({name: instanceName, description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');

        return connection.Instance.please().getOrCreate({name: instanceName}, {description: 'newTest'});
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');
      });
    });

    it('should be able to update an instance', function() {
      return connection.Instance.please().create({name: instanceName, description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');

        return connection.Instance.please().update({name: instance.name}, {description: 'newTest'});
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('newTest');
      });
    });

    it('should be able to update or create instance (UPDATE)', function() {
      return connection.Instance.please().create({name: instanceName, description: 'test'}).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('test');

        return connection.Instance.please().updateOrCreate({name: instance.name}, {description: 'newTest'});
      })
      .then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('newTest');
      });
    });

    it('should be able to update or create instance (CREATE)', function() {
      let properties = {name: instanceName};
      let object = {description: 'updateTest'};
      let defaults = {
          description: 'createTest',
          metadata: {'test': 1}
      };

      return connection.Instance.please().updateOrCreate(properties, object, defaults).then((instance) => {
        should(instance).be.an.Object();
        should(instance).have.property('name').which.is.String().equal(instanceName);
        should(instance).have.property('description').which.is.String().equal('createTest');
        should(instance).have.property('created_at').which.is.String();
        should(instance).have.property('updated_at').which.is.String();
        should(instance).have.property('links').which.is.Object();
        should(instance).have.property('owner').which.is.Object();
        should(instance).have.property('metadata').which.is.Object();
      });
    });

    it('should be able to get first instance (SUCCESS)', function() {
      const names = [
        `${instanceName}_1`,
        `${instanceName}_2`
      ];

      return Promise
        .all(_.map(names, (name) => connection.Instance.please().create({name})))
        .then(() => {
          return connection.Instance.please().first();
        })
        .then((instance) => {
          should(instance).be.an.Object();
        })
        .finally(() => {
          return Promise.all(_.map(names, (name) => connection.Instance.please().delete({name})));
        });
    });

    it('should be able to change page size', function() {
      const names = [
        `${instanceName}_1`,
        `${instanceName}_2`
      ];

      return Promise
        .all(_.map(names, (name) => connection.Instance.please().create({name: name})))
        .then((instances) => {
          should(instances).be.an.Array();
          return connection.Instance.please().pageSize(1);
        })
        .then((instances) => {
          should(instances).be.an.Array().with.length(1);
        })
        .finally(() => {
          return Promise.all(_.map(names, (name) => connection.Instance.please().delete({name: name})));
        });
    });

    it('should be able to change ordering', function() {
      const names = [
        `${instanceName}_1`,
        `${instanceName}_2`
      ];
      let ascInstances = null;

      return Promise
        .all(_.map(names, (name) => connection.Instance.please().create({name: name})))
        .then((instances) => {
          should(instances).be.an.Array().with.length(2);
          return connection.Instance.please().ordering('asc');
        })
        .then((instances) => {
          should(instances).be.an.Array().with.length(2);
          ascInstances = instances;
          return connection.Instance.please().ordering('desc');
        }).then((descInstances) => {
          const ascNames = _.map(ascInstances, 'name');
          const descNames = _.map(descInstances, 'name');
          descNames.reverse();

          should(descInstances).be.an.Array().with.length(2);
          _.forEach(ascNames, (ascName, index) => {
            should(ascName).be.equal(descNames[index]);
          });
        })
        .finally(() => {
          return Promise.all(_.map(names, (name) => connection.Instance.please().delete({name: name})));
        });
    });

    it('should be able to get raw data', function() {
      return connection.Instance.please().list().raw().then((response) => {
        should(response).be.a.Object();
        should(response).have.property('objects').which.is.Array();
        should(response).have.property('next').which.is.null();
        should(response).have.property('prev').which.is.null();
      });
    });

  });

});
<|endoftext|>


<commit_before>jest.autoMockOff();

const getProjectConfig = require('../../src/config/ios').projectConfig;
const mockFs = require('mock-fs');
const projects = require('../fixtures/projects');

describe('ios::getProjectConfig', () => {
  const userConfig = {};

  beforeEach(() => mockFs({ testDir: projects }));

  it('should return an object with ios project configuration', () => {
    const folder = 'testDir/nested';

    expect(typeof getProjectConfig(folder, userConfig)).toBe('object');
  });

  it('should return `null` if ios project was not found', () => {
    const folder = 'testDir/empty';

    expect(getProjectConfig(folder, userConfig)).toBe(null);
  });

  afterEach(mockFs.restore);
});
<commit_msg>Remove before/afterEach hooks in ios/getProjectConfig.js<commit_after>jest.autoMockOff();

const getProjectConfig = require('../../src/config/ios').projectConfig;
const mockFs = require('mock-fs');
const projects = require('../fixtures/projects');

describe('ios::getProjectConfig', () => {
  const userConfig = {};

  it('should return an object with ios project configuration', () => {
    const folder = 'testDir/nested';

    expect(typeof getProjectConfig(folder, userConfig)).toBe('object');
  });

  it('should return `null` if ios project was not found', () => {
    const folder = 'testDir/empty';

    expect(getProjectConfig(folder, userConfig)).toBe(null);
  });
});
<|endoftext|>


<commit_before><commit_msg>changed screen fit size function to run on load<commit_after><|endoftext|>


<commit_before>'use strict';

const expect = require('chai').expect;

describe('Tag Errors', () => {
  const Tag = require('../../../lib/extend/tag');

  const assertNunjucksError = (err, line, type) => {
    console.log(err.name, err.line, err.type);
    console.log(err.message);

    err.should.have.property('name', 'Nunjucks Error');
    err.should.have.property('message');
    err.should.have.property('line', line);
    err.should.have.property('type', type);
  };

  it('unknown tag', () => {
    const tag = new Tag();

    const body = [
      '{% abc %}',
      '  content',
      '{% endabc %}'
    ].join('\n');

    return tag.render(body)
      .then(result => {
        console.log(result);
        throw new Error('should return error');
      })
      .catch(err => {
        assertNunjucksError(err, 1, 'unknown block tag: abc');
      });
  });

  it('no closing tag 1', () => {
    const tag = new Tag();

    tag.register('test',
      (args, content) => {},
      { ends: true });

    const body = [
      '{% test %}',
      '  content'
    ].join('\n');

    return tag.render(body)
      .then(result => {
        console.log(result);
        throw new Error('should return error');
      })
      .catch(err => {
        err.should.have.property('name', 'Template render error');
        err.should.have.property('message');
        expect(err.message).to.contain('unexpected end of file');
      });
  });

  it('no closing tag 2', () => {
    const tag = new Tag();

    tag.register('test',
      (args, content) => {},
      { ends: true });

    const body = [
      '{% test %}',
      '  content',
      '{% test %}'
    ].join('\n');

    return tag.render(body)
      .then(result => {
        console.log(result);
        throw new Error('should return error');
      })
      .catch(err => {
        err.should.have.property('name', 'Template render error');
        err.should.have.property('message');
        expect(err.message).to.contain('unexpected end of file');
      });
  });

  it('curly braces', () => {
    const tag = new Tag();

    const body = [
      '{{docker ps -aq | map docker inspect -f "{{.Name}} {{.Mounts}}"}}'
    ].join('\n');

    return tag.render(body)
      .then(result => {
        console.log(result);
        throw new Error('should return error');
      })
      .catch(err => {
        assertNunjucksError(err, 1, 'expected variable end');
      });
  });

  it('nested curly braces', () => {
    const tag = new Tag();

    tag.register('test',
      (args, content) => {},
      { ends: true });

    const body = [
      '{% test %}',
      '  {{docker ps -aq | map docker inspect -f "{{.Name}} {{.Mounts}}"}}',
      '{% endtest %}'
    ].join('\n');

    return tag.render(body)
      .then(result => {
        console.log(result);
        throw new Error('should return error');
      })
      .catch(err => {
        assertNunjucksError(err, 2, 'expected variable end');
      });
  });

});
<commit_msg>refactor(test-extend-tag_errors): async/await (#4022)<commit_after>'use strict';

describe('Tag Errors', () => {
  const Tag = require('../../../lib/extend/tag');

  const assertNunjucksError = (err, line, type) => {
    err.should.have.property('name', 'Nunjucks Error');
    err.should.have.property('message');
    err.should.have.property('line', line);
    err.should.have.property('type', type);
  };

  it('unknown tag', async () => {
    const tag = new Tag();

    const body = [
      '{% abc %}',
      '  content',
      '{% endabc %}'
    ].join('\n');

    try {
      await tag.render(body);
    } catch (err) {
      assertNunjucksError(err, 1, 'unknown block tag: abc');
    }
  });

  it('no closing tag 1', async () => {
    const tag = new Tag();

    tag.register('test',
      (args, content) => {},
      { ends: true });

    const body = [
      '{% test %}',
      '  content'
    ].join('\n');

    try {
      await tag.render(body);
    } catch (err) {
      err.should.have.property('name', 'Template render error');
      err.should.have.property('message');
      err.message.includes('unexpected end of file').should.eql(true);
    }
  });

  it('no closing tag 2', async () => {
    const tag = new Tag();

    tag.register('test',
      (args, content) => {},
      { ends: true });

    const body = [
      '{% test %}',
      '  content',
      '{% test %}'
    ].join('\n');

    try {
      await tag.render(body);
    } catch (err) {
      err.should.have.property('name', 'Template render error');
      err.should.have.property('message');
      err.message.includes('unexpected end of file').should.eql(true);
    }
  });

  it('curly braces', async () => {
    const tag = new Tag();

    const body = [
      '{{docker ps -aq | map docker inspect -f "{{.Name}} {{.Mounts}}"}}'
    ].join('\n');

    try {
      await tag.render(body);
    } catch (err) {
      assertNunjucksError(err, 1, 'expected variable end');
    }
  });

  it('nested curly braces', async () => {
    const tag = new Tag();

    tag.register('test',
      (args, content) => {},
      { ends: true });

    const body = [
      '{% test %}',
      '  {{docker ps -aq | map docker inspect -f "{{.Name}} {{.Mounts}}"}}',
      '{% endtest %}'
    ].join('\n');

    try {
      await tag.render(body);
    } catch (err) {
      assertNunjucksError(err, 2, 'expected variable end');
    }
  });
});
<|endoftext|>


<commit_before>/**
 * Created by Mariandi on 11/03/2014.
 */
/*global angular*/
'use strict';

angular.module('anguvideo',[])
    .directive("anguvideo", ['$sce', '$interval', function ($sce, $interval) {
        return {
            restrict: 'EA',
            scope: {
                source: '=ngModel',
                width: '@',
                height: '@'
            },
            replace: true,
            template: '
' +
                            '' +
                      '
',
            link: function (scope, element, attrs) {

              var player;
              scope.timer, scope.timeSpent = [];

              function onPlayerStateChange(event) {
                if (!event.data) {
                  scope.$emit("anguvideo:finishVideo");
                }
                if(event.data === 1) { // Started playing
                      if(!scope.timeSpent.length){
                          for(var i=0, l=parseInt(player.getDuration()); i<l; i++) scope.timeSpent.push(false);
                      }
                    scope.timer = $interval(record,100);
                  } else {
                   $interval.cancel(scope.timer);
                }
              }
              (function onYouTubeIframeAPIReady() {
                player = new YT.Player('playerYV', {
                  events: {
                    'onStateChange': onPlayerStateChange
                  }
                });
              }());

              function record(){
              	scope.timeSpent[ parseInt(player.getCurrentTime()) ] = true;
              	showPercentage();
              }

              function showPercentage(){
                  var percent = 0;
                  for(var i=0, l=scope.timeSpent.length; i<l; i++){
                      if(scope.timeSpent[i]) percent++;
                  }
                  percent = Math.round(percent / scope.timeSpent.length * 100);
                  console.log(percent + "%");
                  if(percent >= 70){
                    broadcastWatchedMinPercentage();
                    $interval.cancel(scope.timer);
                  }
              }

              function broadcastWatchedMinPercentage(){
                if(!scope.watchedMinPercentage){
                  scope.$emit("anguvideo:watchedMinPercentage");
                  scope.watchedMinPercentage = true;
                }
              }

                var origin = location.origin;
                var embedFriendlyUrl = "",
                    urlSections,
                    index;

                var youtubeParams = (attrs.hideControls ? '?autoplay=0&showinfo=0&controls=0&enablejsapi=1&origin='+origin : '?autoplay=0&enablejsapi=1&origin='+origin);

                scope.$watch('source', function (newVal) {
                    if (newVal) {
                        /*
                        * Need to convert the urls into a friendly url that can be embedded and be used in the available online players the services have provided
                        * for youtube: src="//www.youtube.com/embed/{{video_id}}"
                        * for vimeo: src="http://player.vimeo.com/video/{{video_id}}
                        */
                        scope.timer, scope.timeSpent = [];
                        scope.watchedMinPercentage = 0;
                        if (newVal.indexOf("vimeo") >= 0) { // Displaying a vimeo video
                            if (newVal.indexOf("player.vimeo") >= 0) {
                                embedFriendlyUrl = newVal;
                            } else {
                                embedFriendlyUrl = newVal.replace("https:", "http:");
                                urlSections = embedFriendlyUrl.split(".com/");
                                embedFriendlyUrl = embedFriendlyUrl.replace("vimeo", "player.vimeo");
                                embedFriendlyUrl = embedFriendlyUrl.replace("/" + urlSections[urlSections.length - 1], "/video/" + urlSections[urlSections.length - 1] + "");
                                embedFriendlyUrl += '?autoplay=0&api=1&player_id=playerYV';
                            }

                            $(function() {
                                  var iframe = $('#playerYV')[0];
                                  var player = $f(iframe);
                                  // When the player is ready, add listeners for pause, finish, and playProgress
                                  player.addEvent('ready', function() {
                                      player.addEvent('pause', function(){
                                        $interval.cancel(scope.timer);
                                      });
                                      player.addEvent('finish', function(){
                                        scope.$emit("anguvideo:finishVideo");
                                        $interval.cancel(scope.timer);
                                      });
                                      player.addEvent('play', function(){
                                        var PlayerVimeoDuration, PlayerVimeoCurrentTime;
                                        player.api('getDuration', function(PlayerVimeoDuration) {
                                          if(!scope.timeSpent.length){
                                            for(var i=0, l=parseInt(PlayerVimeoDuration); i<l; i++) scope.timeSpent.push(false);
                                          }
                                        });
                                      });
                                      player.addEvent('playProgress', function(data, id){
                                        scope.timeSpent[parseInt(data.seconds)] = true;
                                        showPercentage();
                                      });
                                  });
                                  scope.$on("anguvideo:watchedMinPercentage", function(){
                                    player.removeEvent('play');
                                    player.removeEvent('playProgress');
                                    player = undefined;
                                    iframe = undefined;
                                  });
                            });

                        } else if (newVal.indexOf("youtu.be") >= 0) {

                            index = newVal.indexOf(".be/");

                            embedFriendlyUrl = newVal.slice(index + 4, newVal.length);
                            embedFriendlyUrl = "http://www.youtube.com/embed/" + embedFriendlyUrl + youtubeParams;

                        } else if (newVal.indexOf("youtube.com") >= 0) { // displaying a youtube video
                            if (newVal.indexOf("embed") >= 0) {
                                embedFriendlyUrl = newVal + youtubeParams;
                            } else {
                                embedFriendlyUrl = newVal.replace("/watch?v=", "/embed/") + youtubeParams;
                            }
                        }

                        scope.url = $sce.trustAsResourceUrl(embedFriendlyUrl);
                        //console.log("done",  scope.url, embedFriendlyUrl);

                    }

                });

                scope.$on("$destroy",function(){
                  $interval.cancel(scope.timer);
                });
                element.on("$destroy",function() {
                  $interval.cancel(scope.timer);
                  scope.watchedMinPercentage = 0;
                })
            }
        };
    }]);
<commit_msg>cancelando timer ao terminar o video<commit_after>/**
 * Created by Mariandi on 11/03/2014.
 */
/*global angular*/
'use strict';

angular.module('anguvideo',[])
    .directive("anguvideo", ['$sce', '$interval', function ($sce, $interval) {
        return {
            restrict: 'EA',
            scope: {
                source: '=ngModel',
                width: '@',
                height: '@'
            },
            replace: true,
            template: '
' +
                            '' +
                      '
',
            link: function (scope, element, attrs) {

              var player;
              scope.timer, scope.timeSpent = [];

              function onPlayerStateChange(event) {
                if (!event.data) {
                  scope.$emit("anguvideo:finishVideo");
                  $interval.cancel(scope.timer);
                }
                if(event.data === 1) { // Started playing
                      if(!scope.timeSpent.length){
                          for(var i=0, l=parseInt(player.getDuration()); i<l; i++) scope.timeSpent.push(false);
                      }
                    scope.timer = $interval(record,100);
                  } else {
                   $interval.cancel(scope.timer);
                }
              }
              (function onYouTubeIframeAPIReady() {
                player = new YT.Player('playerYV', {
                  events: {
                    'onStateChange': onPlayerStateChange
                  }
                });
              }());

              function record(){
              	scope.timeSpent[ parseInt(player.getCurrentTime()) ] = true;
              	showPercentage();
              }

              function showPercentage(){
                  var percent = 0;
                  for(var i=0, l=scope.timeSpent.length; i<l; i++){
                      if(scope.timeSpent[i]) percent++;
                  }
                  percent = Math.round(percent / scope.timeSpent.length * 100);
                  console.log(percent + "%");
                  if(percent >= 70){
                    broadcastWatchedMinPercentage();
                    $interval.cancel(scope.timer);
                  }
              }

              function broadcastWatchedMinPercentage(){
                if(!scope.watchedMinPercentage){
                  scope.$emit("anguvideo:watchedMinPercentage");
                  scope.watchedMinPercentage = true;
                }
              }

                var origin = location.origin;
                var embedFriendlyUrl = "",
                    urlSections,
                    index;

                var youtubeParams = (attrs.hideControls ? '?autoplay=0&showinfo=0&controls=0&enablejsapi=1&origin='+origin : '?autoplay=0&enablejsapi=1&origin='+origin);

                scope.$watch('source', function (newVal) {
                    if (newVal) {
                        /*
                        * Need to convert the urls into a friendly url that can be embedded and be used in the available online players the services have provided
                        * for youtube: src="//www.youtube.com/embed/{{video_id}}"
                        * for vimeo: src="http://player.vimeo.com/video/{{video_id}}
                        */
                        scope.timer, scope.timeSpent = [];
                        scope.watchedMinPercentage = 0;
                        if (newVal.indexOf("vimeo") >= 0) { // Displaying a vimeo video
                            if (newVal.indexOf("player.vimeo") >= 0) {
                                embedFriendlyUrl = newVal;
                            } else {
                                embedFriendlyUrl = newVal.replace("https:", "http:");
                                urlSections = embedFriendlyUrl.split(".com/");
                                embedFriendlyUrl = embedFriendlyUrl.replace("vimeo", "player.vimeo");
                                embedFriendlyUrl = embedFriendlyUrl.replace("/" + urlSections[urlSections.length - 1], "/video/" + urlSections[urlSections.length - 1] + "");
                                embedFriendlyUrl += '?autoplay=0&api=1&player_id=playerYV';
                            }

                            $(function() {
                                  var iframe = $('#playerYV')[0];
                                  var player = $f(iframe);
                                  // When the player is ready, add listeners for pause, finish, and playProgress
                                  player.addEvent('ready', function() {
                                      player.addEvent('pause', function(){
                                        $interval.cancel(scope.timer);
                                      });
                                      player.addEvent('finish', function(){
                                        scope.$emit("anguvideo:finishVideo");
                                        $interval.cancel(scope.timer);
                                      });
                                      player.addEvent('play', function(){
                                        var PlayerVimeoDuration, PlayerVimeoCurrentTime;
                                        player.api('getDuration', function(PlayerVimeoDuration) {
                                          if(!scope.timeSpent.length){
                                            for(var i=0, l=parseInt(PlayerVimeoDuration); i<l; i++) scope.timeSpent.push(false);
                                          }
                                        });
                                      });
                                      player.addEvent('playProgress', function(data, id){
                                        scope.timeSpent[parseInt(data.seconds)] = true;
                                        showPercentage();
                                      });
                                  });
                                  scope.$on("anguvideo:watchedMinPercentage", function(){
                                    player.removeEvent('play');
                                    player.removeEvent('playProgress');
                                    player = undefined;
                                    iframe = undefined;
                                  });
                            });

                        } else if (newVal.indexOf("youtu.be") >= 0) {

                            index = newVal.indexOf(".be/");

                            embedFriendlyUrl = newVal.slice(index + 4, newVal.length);
                            embedFriendlyUrl = "http://www.youtube.com/embed/" + embedFriendlyUrl + youtubeParams;

                        } else if (newVal.indexOf("youtube.com") >= 0) { // displaying a youtube video
                            if (newVal.indexOf("embed") >= 0) {
                                embedFriendlyUrl = newVal + youtubeParams;
                            } else {
                                embedFriendlyUrl = newVal.replace("/watch?v=", "/embed/") + youtubeParams;
                            }
                        }

                        scope.url = $sce.trustAsResourceUrl(embedFriendlyUrl);
                        //console.log("done",  scope.url, embedFriendlyUrl);

                    }

                });

                scope.$on("$destroy",function(){
                  $interval.cancel(scope.timer);
                });
                element.on("$destroy",function() {
                  $interval.cancel(scope.timer);
                  scope.watchedMinPercentage = 0;
                })
            }
        };
    }]);
<|endoftext|>


<commit_before>'use strict';

describe('Controller: AddFoodCtrl', function () {

  // load the controller's module
  beforeEach(module('lbClientApp'));

  var AddFoodCtrl,
    scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    AddFoodCtrl = $controller('AddFoodCtrl', {
      $scope: scope
    });
  }));

  it('foo', function () {
  });
});
<commit_msg>Tests for the "add-food" controller.<commit_after>'use strict';

describe('Controller: AddFoodCtrl', function () {

  // load the controller's module
  beforeEach(module('lbClientApp'));

  var AddFoodCtrl,
    scope;

  // Initialize the controller and a mock scope
  beforeEach(inject(function ($controller, $rootScope) {
    scope = $rootScope.$new();
    AddFoodCtrl = $controller('AddFoodCtrl', {
      $scope: scope
    });
  }));

  it('returns the proper quantity label for foods', function () {
    scope.item = {
      type: 'food'
    };
    expect(scope.quantityLabel()).toBe('grams');
  });

  it('returns the proper quantity label for beverages', function () {
    scope.item = {
      type: 'beverage'
    };
    expect(scope.quantityLabel()).toBe('milliliters');
  });

  it('properly detects a food item', function () {
    scope.item = {
      type: 'food'
    };
    expect(scope.isFood()).toBeTruthy();
    expect(scope.isBeverage()).toBeFalsy();
  });

  it('properly detects a beverage item', function () {
    scope.item = {
      type: 'beverage'
    };
    expect(scope.isFood()).toBeFalsy();
    expect(scope.isBeverage()).toBeTruthy();
  });

  it('properly select a food item', function () {
    scope.item = {
      type: 'beverage'
    };
    expect(scope.isFood()).toBeFalsy();
    expect(scope.isBeverage()).toBeTruthy();
    scope.selectFood();
    expect(scope.isFood()).toBeTruthy();
    expect(scope.isBeverage()).toBeFalsy();
  });

  it('properly select a beverage item', function () {
    scope.item = {
      type: 'food'
    };
    expect(scope.isFood()).toBeTruthy();
    expect(scope.isBeverage()).toBeFalsy();
    scope.selectBeverage();
    expect(scope.isFood()).toBeFalsy();
    expect(scope.isBeverage()).toBeTruthy();
  });
});
<|endoftext|>


<commit_before><commit_msg>initial commit d3.js<commit_after><|endoftext|>


<commit_before><commit_msg>qweqwe<commit_after><|endoftext|>


<commit_before><commit_msg>Update ip-search.js<commit_after><|endoftext|>


<commit_before><commit_msg>JJV - Adding array detection<commit_after><|endoftext|>


<commit_before><commit_msg>Bump version to 4.1.0 for remaining files.<commit_after><|endoftext|>


<commit_before><commit_msg>added fetchOrderBooks to test.js<commit_after><|endoftext|>


<commit_before><commit_msg>test.js agent → httpsAgent<commit_after><|endoftext|>


<commit_before><commit_msg>ci retrigger<commit_after><|endoftext|>


<commit_before><commit_msg>Just being OCD<commit_after><|endoftext|>


<commit_before>/* eslint-disable
    handle-callback-err,
    no-undef
*/
// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
/*
 * decaffeinate suggestions:
 * DS102: Remove unnecessary code created because of implicit returns
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
const sinon = require('sinon')
const chai = require('chai')
const { should, expect, assert } = chai
const SandboxedModule = require('sandboxed-module')
const EventEmitter = require('events')

describe('ASpellWorker', function () {
  beforeEach(function () {
    this.child_process = {}
    return (this.ASpellWorker = SandboxedModule.require('../../../app/js/ASpellWorker', {
      requires: {
        'logger-sharelatex': {
          log() { },
          info() { },
          err() { }
        },
        'metrics-sharelatex': {
          gauge() { },
          inc() { }
        },
        'child_process': this.child_process
      }
    }))
  })

  describe("creating a worker", function () {
    beforeEach(function () {
      this.pipe = {
        'stdout': new EventEmitter(),
        'stderr': { on: sinon.stub() },
        'stdin': {on: sinon.stub() },
        'on': sinon.stub(),
        'pid': 12345
      }
      this.child_process.spawn = sinon.stub().returns(this.pipe)
      this.pipe.stdout.setEncoding = sinon.stub()
      worker = new this.ASpellWorker('en')

    })

    describe("with normal aspell output", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\ne')
        this.pipe.stdout.emit('data', 'n\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker newline split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en')
        this.pipe.stdout.emit('data', '\n& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

    describe("with everything split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        '& hello\n& world\nen\n& goodbye'.split('').forEach(x => {
          this.pipe.stdout.emit('data', x)
        })
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

  })
})
<commit_msg>fix eslint check<commit_after>/* eslint-disable
    handle-callback-err,
    no-undef
*/
// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
/*
 * decaffeinate suggestions:
 * DS102: Remove unnecessary code created because of implicit returns
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
const sinon = require('sinon')
const chai = require('chai')
const { expect } = chai
const SandboxedModule = require('sandboxed-module')
const EventEmitter = require('events')

describe('ASpellWorker', function () {
  beforeEach(function () {
    this.child_process = {}
    return (this.ASpellWorker = SandboxedModule.require('../../../app/js/ASpellWorker', {
      requires: {
        'logger-sharelatex': {
          log() { },
          info() { },
          err() { }
        },
        'metrics-sharelatex': {
          gauge() { },
          inc() { }
        },
        'child_process': this.child_process
      }
    }))
  })

  describe("creating a worker", function () {
    beforeEach(function () {
      this.pipe = {
        'stdout': new EventEmitter(),
        'stderr': { on: sinon.stub() },
        'stdin': {on: sinon.stub() },
        'on': sinon.stub(),
        'pid': 12345
      }
      this.child_process.spawn = sinon.stub().returns(this.pipe)
      this.pipe.stdout.setEncoding = sinon.stub()
      worker = new this.ASpellWorker('en')

    })

    describe("with normal aspell output", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\ne')
        this.pipe.stdout.emit('data', 'n\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker newline split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en')
        this.pipe.stdout.emit('data', '\n& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

    describe("with everything split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        '& hello\n& world\nen\n& goodbye'.split('').forEach(x => {
          this.pipe.stdout.emit('data', x)
        })
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

  })
})
<|endoftext|>


<commit_before>import getScript from '../../../src/util/get-script';

describe.only('getScript()', () => {
  const src = '//ajax.googleapis.com/ajax/libs/hammerjs/2.0.8/hammer.min.js';
  const query = `script[src="${src}"]`;

  afterEach(() => {
    let el = document.querySelector(query);

    if (el) {
      el.parentNode.removeChild(el);
    }

    return Promise.resolve();
  });

  it('should add script tag to DOM', () => {
    return getScript(src).then(() => {
      expect(document.querySelector(query)).to.be.ok;
    });
  });

  it('should not duplicate script tags', () => {
    let firstScriptResolved = false;

    return getScript(src).then(() => {
      firstScriptResolved = true;

      return getScript(src);
    }).catch((message) => {
      expect(firstScriptResolved).to.be.true;
      expect(message).to.contain('already exists');
      expect(document.querySelectorAll(query)).to.have.length.of(1);
    });
  });
});<commit_msg>remove only<commit_after>import getScript from '../../../src/util/get-script';

describe('getScript()', () => {
  const src = '//ajax.googleapis.com/ajax/libs/hammerjs/2.0.8/hammer.min.js';
  const query = `script[src="${src}"]`;

  afterEach(() => {
    let el = document.querySelector(query);

    if (el) {
      el.parentNode.removeChild(el);
    }

    return Promise.resolve();
  });

  it('should add script tag to DOM', () => {
    return getScript(src).then(() => {
      expect(document.querySelector(query)).to.be.ok;
    });
  });

  it('should not duplicate script tags', () => {
    let firstScriptResolved = false;

    return getScript(src).then(() => {
      firstScriptResolved = true;

      return getScript(src);
    }).catch((message) => {
      expect(firstScriptResolved).to.be.true;
      expect(message).to.contain('already exists');
      expect(document.querySelectorAll(query)).to.have.length.of(1);
    });
  });
});<|endoftext|>


<commit_before>Ui.LBox.extend('Ui.Uploadable',
/**@lends Ui.Uploadable#*/
{
	isDown: false,
	content: undefined,
	input: undefined,

	/**
	 * @constructs
	 * @class
	 * @extends Ui.LBox
	 */
	constructor: function(config) {
		this.getDrawing().style.cursor = 'pointer';

		this.setFocusable(true);
		this.setRole('button');

		this.addEvents('file', 'down', 'up');

		if(navigator.isOpera || navigator.isFirefox3 || navigator.isIE7 || navigator.isIE8)
			this.input = new Ui.UploadableWrapper();
		else
			this.input = new Ui.UploadableFileWrapper();
		this.append(this.input);
		this.connect(this.input, 'file', this.onFile);

		// handle mouse
		this.connect(this.getDrawing(), 'mousedown', this.onMouseDown);

		// handle touches
		this.connect(this.getDrawing(), 'touchstart', this.onTouchStart);
		this.connect(this.getDrawing(), 'touchmove', this.onTouchMove);
		this.connect(this.getDrawing(), 'touchend', this.onTouchEnd);

		// handle keyboard
		this.connect(this.getDrawing(), 'keydown', this.onKeyDown);
		this.connect(this.getDrawing(), 'keyup', this.onKeyUp);
	},

	setDirectoryMode: function(active) {
		this.input.setDirectoryMode(active);
	},

	/**#@+
	 * @private
	 */

	onMouseDown: function(event) {
		if((event.button != 0) || this.getIsDisabled())
			return;

		event.preventDefault();
		event.stopPropagation();

		this.mouseStartX = event.screenX;
		this.mouseStartY = event.screenY;

		if('attachEvent' in this.getDrawing()) {
			this.connect(this.getDrawing(), 'mousemove', this.onMouseMove, true);
			this.connect(this.getDrawing(), 'mouseup', this.onMouseUp, true);
		}
		else {
			this.connect(window, 'mousemove', this.onMouseMove, true);
			this.connect(window, 'mouseup', this.onMouseUp, true);
		}

		this.onDown();
	},

	onMouseMove: function(event) {
		var deltaX = event.screenX - this.mouseStartX;
		var deltaY = event.screenY - this.mouseStartY;
		var delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

		event.preventDefault();
		event.stopPropagation();

		// if the user move to much, release the touch event
		if(delta > 10) {
			this.onUp();

			if('createEvent' in document) {
				this.disconnect(this.getDrawing(), 'mousedown', this.onMouseDown);

				var mouseDownEvent = document.createEvent('MouseEvents');
				mouseDownEvent.initMouseEvent('mousedown', true, true, window, 1, event.screenX, event.screenY,
					event.clientX, event.clientY,
					event.ctrlKey, event.altKey, event.shiftKey,
					event.metaKey, 0, event.target);
				event.target.dispatchEvent(mouseDownEvent);

				this.connect(this.getDrawing(), 'mousedown', this.onMouseDown);
			}
		}
	},

	getIsDown: function() {
		return this.isDown;
	},

	onMouseUp: function(event) {
		if(!this.isDown)
			return;

		event.preventDefault();
		event.stopPropagation();
		if(event.button == 0) {
			this.onUp();
			this.onPress();
		}
	},

	onTouchStart: function(event) {
		if(this.getIsDisabled())
			return;
		if(this.isDown) {
			this.onUp();
			return;
		}
		if(event.targetTouches.length != 1)
			return;

		event.preventDefault();
		event.stopPropagation();

		this.touchStartX = event.targetTouches[0].screenX;
		this.touchStartY = event.targetTouches[0].screenY;
		this.onDown();
	},

	onTouchMove: function(event) {
		if(!this.isDown)
			return;

		var deltaX = event.targetTouches[0].screenX - this.touchStartX;
		var deltaY = event.targetTouches[0].screenY - this.touchStartY;
		var delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

		// if the user move to much, release the touch event
		if(delta > 10) {
			this.onUp();

			this.disconnect(this.getDrawing(), 'touchstart', this.onTouchStart);

			var touchStartEvent = document.createEvent('TouchEvent');
			touchStartEvent.initTouchEvent('touchstart', true, true, window, 0, 0, 0, 0, 0,
				event.ctrlKey, event.altKey, event.shiftKey,
				event.metaKey, event.touches,
				event.targetTouches, event.changedTouches, event.scale, event.rotation);
			event.target.dispatchEvent(touchStartEvent);

			this.connect(this.getDrawing(), 'touchstart', this.onTouchStart);
		}

		event.preventDefault();
		event.stopPropagation();
	},

	onTouchEnd: function(event) {
		if(!this.isDown)
			return;

		event.preventDefault();
		event.stopPropagation();
		this.onUp();
		this.onPress();
		this.focus();
	},

	onKeyDown: function(event) {
		var key = event.which;
		if((key == 13) && !this.getIsDisabled()) {
			event.preventDefault();
			event.stopPropagation();
			this.onDown();
		}
	},

	onKeyUp: function(event) {
		var key = event.which;
		if((key == 13) && !this.getIsDisabled()) {
			event.preventDefault();
			event.stopPropagation();
			this.onUp();
			this.onPress();
		}
	},

	onDown: function() {
		this.isDown = true;
		this.focus();
		this.fireEvent('down', this);
	},

	onUp: function() {
		if('attachEvent' in this.getDrawing()) {
			this.disconnect(this.getDrawing(), 'mousemove', this.onMouseMove);
			this.disconnect(this.getDrawing(), 'mouseup', this.onMouseUp);
		}
		else {
			this.disconnect(window, 'mousemove', this.onMouseMove);
			this.disconnect(window, 'mouseup', this.onMouseUp);
		}
 		this.isDown = false;
		this.fireEvent('up', this);
	},

	onPress: function() {
		if(Ui.UploadableFileWrapper.hasInstance(this.input))
			this.input.select();
	},

	onFile: function(fileWrapper, file) {
		this.fireEvent('file', this, file);
	}
	/**#@-*/
}, {
	setContent: function(content) {
		content = Ui.Element.create(content);
		if(this.content != content) {
			if(this.content != undefined)
				this.remove(this.content);
			if(content != undefined) {
				if(Ui.UploadableWrapper.hasInstance(this.input))
					this.prepend(content);
				else
					this.append(content);
			}
			this.content = content;
		}
	}
});

Ui.Element.extend('Ui.UploadableFileWrapper',
/**@lends Ui.UploadableFileWrapper#*/
{
	formDrawing: undefined,
	inputDrawing: undefined,
	iframeDrawing: undefined,
	directoryMode: false,

	/**
	 * @constructs
	 * @class
	 * @extends Ui.Element
	 */
	constructor: function(config) {
		this.setVerticalAlign('top');
		this.setHorizontalAlign('left');
		this.setClipToBounds(true);
		this.addEvents('file');
	},

	select: function() {
		this.inputDrawing.click();
	},

	setDirectoryMode: function(active) {
		this.directoryMode = active;
		if(this.inputDrawing != undefined) {
			if(this.directoryMode)
				this.inputDrawing.setAttribute('webkitdirectory', '');
			else
				this.inputDrawing.removeAttribute('webkitdirectory');
		}
	},

	/*#@+
	 * @private
	 */
	createInput: function() {
		this.formDrawing = document.createElement('form');
		this.formDrawing.method = 'POST';
		this.formDrawing.enctype = 'multipart/form-data';
		// needed for IE < 9
		this.formDrawing.encoding = 'multipart/form-data';

		this.inputDrawing = document.createElement('input');
		this.inputDrawing.type = 'file';
		this.inputDrawing.setAttribute('name', 'file');
		if(this.directoryMode)
			this.inputDrawing.setAttribute('webkitdirectory', '');

		this.connect(this.inputDrawing, 'change', this.onChange);
		this.formDrawing.appendChild(this.inputDrawing);

		if(navigator.supportFileAPI) {
			this.getDrawing().appendChild(this.formDrawing);
		}
		else {
			// create an iframe now for the async POST
			// needed because browser like IE9 don't support
			// unloading the input file from the DOM (else it is cleared)
			this.iframeDrawing = document.createElement('iframe');
			this.iframeDrawing.style.position = 'absolute';
			this.iframeDrawing.style.top = '0px';
			this.iframeDrawing.style.left = '0px';
			this.iframeDrawing.style.width = '0px';
			this.iframeDrawing.style.height = '0px';
			this.iframeDrawing.style.clip = 'rect(0px 0px 0px 0px)';

			document.body.appendChild(this.iframeDrawing);
			this.iframeDrawing.contentWindow.document.write("<!DOCTYPE html>");
			this.iframeDrawing.contentWindow.document.body.appendChild(this.formDrawing);
		}
	},

	onChange: function(event) {
		event.preventDefault();
		event.stopPropagation();

		if(navigator.supportFileAPI) {
			for(var i = 0; i < this.inputDrawing.files.length; i++)
				this.fireEvent('file', this, new Core.File({ fileApi: this.inputDrawing.files[i] }));
		}
		else {
			this.disconnect(this.inputDrawing, 'change', this.onChange);
			this.fireEvent('file', this, new Core.File({ iframe: this.iframeDrawing, form: this.formDrawing, fileInput: this.inputDrawing }));
			this.createInput();
		}
	}

	/**#@-*/
},
/**@lends Ui.UploadableFileWrapper#*/
{
	onLoad: function() {
		Ui.UploadableFileWrapper.base.onLoad.call(this);
		this.createInput();
	},

	onUnload: function() {
		this.disconnect(this.inputDrawing, 'change', this.onChange);
        if(this.iframeDrawing != undefined)
            document.body.removeChild(this.iframeDrawing);
		Ui.UploadableFileWrapper.base.onUnload.call(this);
	}
});

Ui.Element.extend('Ui.UploadableWrapper',
/**@lends Ui.UploadableWrapper#*/
{
	formDrawing: undefined,
	inputDrawing: undefined,
	directoryMode: false,

	/**
	 * @constructs
	 * @class
	 * @extends Ui.Element
	 */
	constructor: function(config) {
		this.setClipToBounds(true);
		this.setOpacity(0);
		this.addEvents('file');
	},

	setDirectoryMode: function(active) {
	},

	/*#@+
	 * @private
	 */
	createInput: function() {

		this.formDrawing = document.createElement('form');
		this.formDrawing.method = 'POST';
		this.formDrawing.enctype = 'multipart/form-data';
		this.formDrawing.encoding = 'multipart/form-data';
		this.formDrawing.style.display = 'block';
		this.formDrawing.style.position = 'absolute';
		this.formDrawing.style.left = '0px';
		this.formDrawing.style.top = '0px';
		this.formDrawing.style.width = this.getLayoutWidth()+'px';
		this.formDrawing.style.height = this.getLayoutHeight()+'px';

		this.inputDrawing = document.createElement('input');
		this.inputDrawing.type = 'file';
		this.inputDrawing.name = 'file';
		this.inputDrawing.style.fontSize = '200px';
		this.inputDrawing.style.display = 'block';
		this.inputDrawing.style.cursor = 'pointer';
		this.inputDrawing.style.position = 'absolute';
		this.inputDrawing.style.left = '0px';
		this.inputDrawing.style.top = '0px';
		this.inputDrawing.style.width = this.getLayoutWidth()+'px';
		this.inputDrawing.style.height = this.getLayoutHeight()+'px';
		if(navigator.isIE7 || navigator.isIE8)
			this.inputDrawing.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)';
		this.formDrawing.appendChild(this.inputDrawing);

		this.connect(this.inputDrawing, 'change', this.onChange);

		return this.formDrawing;
	},

	onChange: function(event) {
		if(!navigator.isOpera && navigator.supportFileAPI) {
			for(var i = 0; i < this.inputDrawing.files.length; i++)
				this.fireEvent('file', this, new Core.File({ fileApi: this.inputDrawing.files[i] }));
		}
		else {
			this.getDrawing().removeChild(this.formDrawing);

			var iframeDrawing = document.createElement('iframe');
			iframeDrawing.style.position = 'absolute';
			iframeDrawing.style.top = '0px';
			iframeDrawing.style.left = '0px';
			iframeDrawing.style.width = '0px';
			iframeDrawing.style.height = '0px';
			iframeDrawing.style.clip = 'rect(0px 0px 0px 0px)';

			document.body.appendChild(iframeDrawing);
			iframeDrawing.contentWindow.document.write("<!DOCTYPE html>");
			iframeDrawing.contentWindow.document.body.appendChild(this.formDrawing);

			this.disconnect(this.inputDrawing, 'change', this.onChange);
			this.fireEvent('file', this, new Core.File({ iframe: iframeDrawing, form: this.formDrawing, fileInput: this.inputDrawing }));

			this.getDrawing().appendChild(this.createInput());
		}
	}
	/**#@-*/
},
/**@lends Ui.UploadableWrapper#*/
{
	render: function() {
		return this.createInput();
	},

	arrangeCore: function(width, height) {
		this.formDrawing.style.width = width+'px';
		this.formDrawing.style.height = height+'px';
		this.inputDrawing.style.width = width+'px';
		this.inputDrawing.style.height = height+'px';
	}
});

navigator.supportFormData = true;
try {
	new FormData();
}
catch(err) {
	navigator.supportFormData = false;
}

Ui.Uploadable.testInput = document.createElement('input');
navigator.supportFileAPI = 'files' in Ui.Uploadable.testInput;
navigator.supportUploadDirectory = 'webkitdirectory' in Ui.Uploadable.testInput;
delete(Ui.Uploadable.testInput);

<commit_msg>cleanup Ui.Uploadable and correct a bug in iOS 6<commit_after>Ui.Pressable.extend('Ui.Uploadable',
/**@lends Ui.Uploadable#*/
{
	content: undefined,
	input: undefined,

	/**
	 * @constructs
	 * @class
	 * @extends Ui.LBox
	 */
	constructor: function(config) {
		this.getDrawing().style.cursor = 'pointer';

		this.setFocusable(true);
		this.setRole('button');

		this.addEvents('file');

		if(navigator.isOpera || navigator.isFirefox3 || navigator.isIE7 || navigator.isIE8)
			this.input = new Ui.UploadableWrapper();
		else
			this.input = new Ui.UploadableFileWrapper();
		this.append(this.input);
		this.connect(this.input, 'file', this.onFile);

		this.connect(this, 'press', this.onPress);
	},

	setDirectoryMode: function(active) {
		this.input.setDirectoryMode(active);
	},

	/**#@+
	 * @private
	 */

	onPress: function() {
		if(Ui.UploadableFileWrapper.hasInstance(this.input)) {
			// delay the task because of the iOS thread problem
			var task = new Core.DelayedTask({ scope: this, delay: 0, callback: function() {
				this.input.select();
			} });
		}
	},

	onFile: function(fileWrapper, file) {
		this.fireEvent('file', this, file);
	}
	/**#@-*/
}, {
	setContent: function(content) {
		content = Ui.Element.create(content);
		if(this.content != content) {
			if(this.content != undefined)
				this.remove(this.content);
			if(content != undefined) {
				if(Ui.UploadableWrapper.hasInstance(this.input))
					this.prepend(content);
				else
					this.append(content);
			}
			this.content = content;
		}
	}
});

Ui.Element.extend('Ui.UploadableFileWrapper',
/**@lends Ui.UploadableFileWrapper#*/
{
	formDrawing: undefined,
	inputDrawing: undefined,
	iframeDrawing: undefined,
	directoryMode: false,

	/**
	 * @constructs
	 * @class
	 * @extends Ui.Element
	 */
	constructor: function(config) {
		this.setVerticalAlign('top');
		this.setHorizontalAlign('left');
		this.setClipToBounds(true);
		this.addEvents('file');
	},

	select: function() {
		this.inputDrawing.click();
	},

	setDirectoryMode: function(active) {
		this.directoryMode = active;
		if(this.inputDrawing != undefined) {
			if(this.directoryMode)
				this.inputDrawing.setAttribute('webkitdirectory', '');
			else
				this.inputDrawing.removeAttribute('webkitdirectory');
		}
	},

	/*#@+
	 * @private
	 */
	createInput: function() {
		this.formDrawing = document.createElement('form');
		this.formDrawing.method = 'POST';
		this.formDrawing.enctype = 'multipart/form-data';
		// needed for IE < 9
		this.formDrawing.encoding = 'multipart/form-data';

		this.inputDrawing = document.createElement('input');
		this.inputDrawing.type = 'file';
		this.inputDrawing.setAttribute('name', 'file');
		if(this.directoryMode)
			this.inputDrawing.setAttribute('webkitdirectory', '');

		this.connect(this.inputDrawing, 'change', this.onChange);
		this.formDrawing.appendChild(this.inputDrawing);

		if(navigator.supportFileAPI) {
			this.getDrawing().appendChild(this.formDrawing);
		}
		else {
			// create an iframe now for the async POST
			// needed because browser like IE9 don't support
			// unloading the input file from the DOM (else it is cleared)
			this.iframeDrawing = document.createElement('iframe');
			this.iframeDrawing.style.position = 'absolute';
			this.iframeDrawing.style.top = '0px';
			this.iframeDrawing.style.left = '0px';
			this.iframeDrawing.style.width = '0px';
			this.iframeDrawing.style.height = '0px';
			this.iframeDrawing.style.clip = 'rect(0px 0px 0px 0px)';

			document.body.appendChild(this.iframeDrawing);
			this.iframeDrawing.contentWindow.document.write("<!DOCTYPE html>");
			this.iframeDrawing.contentWindow.document.body.appendChild(this.formDrawing);
		}
	},

	onChange: function(event) {
		event.preventDefault();
		event.stopPropagation();

		if(navigator.supportFileAPI) {
			for(var i = 0; i < this.inputDrawing.files.length; i++)
				this.fireEvent('file', this, new Core.File({ fileApi: this.inputDrawing.files[i] }));
		}
		else {
			this.disconnect(this.inputDrawing, 'change', this.onChange);
			this.fireEvent('file', this, new Core.File({ iframe: this.iframeDrawing, form: this.formDrawing, fileInput: this.inputDrawing }));
			this.createInput();
		}
	}

	/**#@-*/
},
/**@lends Ui.UploadableFileWrapper#*/
{
	onLoad: function() {
		Ui.UploadableFileWrapper.base.onLoad.call(this);
		this.createInput();
	},

	onUnload: function() {
		this.disconnect(this.inputDrawing, 'change', this.onChange);
        if(this.iframeDrawing != undefined)
            document.body.removeChild(this.iframeDrawing);
		Ui.UploadableFileWrapper.base.onUnload.call(this);
	}
});

Ui.Element.extend('Ui.UploadableWrapper',
/**@lends Ui.UploadableWrapper#*/
{
	formDrawing: undefined,
	inputDrawing: undefined,
	directoryMode: false,

	/**
	 * @constructs
	 * @class
	 * @extends Ui.Element
	 */
	constructor: function(config) {
		this.setClipToBounds(true);
		this.setOpacity(0);
		this.addEvents('file');
	},

	setDirectoryMode: function(active) {
	},

	/*#@+
	 * @private
	 */
	createInput: function() {

		this.formDrawing = document.createElement('form');
		this.formDrawing.method = 'POST';
		this.formDrawing.enctype = 'multipart/form-data';
		this.formDrawing.encoding = 'multipart/form-data';
		this.formDrawing.style.display = 'block';
		this.formDrawing.style.position = 'absolute';
		this.formDrawing.style.left = '0px';
		this.formDrawing.style.top = '0px';
		this.formDrawing.style.width = this.getLayoutWidth()+'px';
		this.formDrawing.style.height = this.getLayoutHeight()+'px';

		this.inputDrawing = document.createElement('input');
		this.inputDrawing.type = 'file';
		this.inputDrawing.name = 'file';
		this.inputDrawing.style.fontSize = '200px';
		this.inputDrawing.style.display = 'block';
		this.inputDrawing.style.cursor = 'pointer';
		this.inputDrawing.style.position = 'absolute';
		this.inputDrawing.style.left = '0px';
		this.inputDrawing.style.top = '0px';
		this.inputDrawing.style.width = this.getLayoutWidth()+'px';
		this.inputDrawing.style.height = this.getLayoutHeight()+'px';
		if(navigator.isIE7 || navigator.isIE8)
			this.inputDrawing.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(Opacity=0)';
		this.formDrawing.appendChild(this.inputDrawing);

		this.connect(this.inputDrawing, 'change', this.onChange);

		return this.formDrawing;
	},

	onChange: function(event) {
		if(!navigator.isOpera && navigator.supportFileAPI) {
			for(var i = 0; i < this.inputDrawing.files.length; i++)
				this.fireEvent('file', this, new Core.File({ fileApi: this.inputDrawing.files[i] }));
		}
		else {
			this.getDrawing().removeChild(this.formDrawing);

			var iframeDrawing = document.createElement('iframe');
			iframeDrawing.style.position = 'absolute';
			iframeDrawing.style.top = '0px';
			iframeDrawing.style.left = '0px';
			iframeDrawing.style.width = '0px';
			iframeDrawing.style.height = '0px';
			iframeDrawing.style.clip = 'rect(0px 0px 0px 0px)';

			document.body.appendChild(iframeDrawing);
			iframeDrawing.contentWindow.document.write("<!DOCTYPE html>");
			iframeDrawing.contentWindow.document.body.appendChild(this.formDrawing);

			this.disconnect(this.inputDrawing, 'change', this.onChange);
			this.fireEvent('file', this, new Core.File({ iframe: iframeDrawing, form: this.formDrawing, fileInput: this.inputDrawing }));

			this.getDrawing().appendChild(this.createInput());
		}
	}
	/**#@-*/
},
/**@lends Ui.UploadableWrapper#*/
{
	render: function() {
		return this.createInput();
	},

	arrangeCore: function(width, height) {
		this.formDrawing.style.width = width+'px';
		this.formDrawing.style.height = height+'px';
		this.inputDrawing.style.width = width+'px';
		this.inputDrawing.style.height = height+'px';
	}
});

navigator.supportFormData = true;
try {
	new FormData();
}
catch(err) {
	navigator.supportFormData = false;
}

Ui.Uploadable.testInput = document.createElement('input');
navigator.supportFileAPI = 'files' in Ui.Uploadable.testInput;
navigator.supportUploadDirectory = 'webkitdirectory' in Ui.Uploadable.testInput;
delete(Ui.Uploadable.testInput);

<|endoftext|>


<commit_before>// 66: object-literal - getter
// To do: make all tests pass, leave the assert lines unchanged!

var assert = require("assert");

describe('An object literal can also contain getters', () => {

  it('just prefix the property with `get` (and make it a function)', function() {
    const obj = {
      x() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
  });

  it('must have NO parameters', function() {
    const obj = {
      x(param) { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
  });

  it('can be a computed property (an expression enclosed in `[]`)', function() {
    const keyName = 'x';
    const obj = {
      get keyName() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
  });

  it('can be removed using delete', function() {
    const obj = {
      get x() { return 'ax'; }
    };

    assert.equal(obj.x, void 0);
  });

  // The following dont seem to work in the current transpiler version
  // but should be correct, as stated here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
  // It might be corrected later, new knowledge welcome.

  //it('must not overlap with a pure property', function() {
  //  const obj = {
  //    x: 1,
  //    get x() { return 'ax'; }
  //  };
  //
  //  assert.equal(obj.x, 'ax');
  //});
  //
  //it('multiple `get` for the same property are not allowed', function() {
  //  const obj = {
  //    x: 1,
  //    get x() { return 'ax'; },
  //    get x() { return 'ax1'; }
  //  };
  //
  //  assert.equal(obj.x, 'ax');
  //});
});

<commit_msg>fix 66-object-literal-getter.js<commit_after>// 66: object-literal - getter
// To do: make all tests pass, leave the assert lines unchanged!

var assert = require("assert");

describe('An object literal can also contain getters', () => {

  it('just prefix the property with `get` (and make it a function)', function() {
    const obj = {
      get x() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
  });

  it('must have NO parameters', function() {
    const obj = {
      get x() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
  });

  it('can be a computed property (an expression enclosed in `[]`)', function() {
    const keyName = 'x';
    const obj = {
      get [keyName]() { return 'ax'; }
    };

    assert.equal(obj.x, 'ax');
  });

  it('can be removed using delete', function() {
    const obj = {
      get x() { return 'ax'; }
    };

    delete obj.x;

    assert.equal(obj.x, void 0);
  });

  // The following dont seem to work in the current transpiler version
  // but should be correct, as stated here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
  // It might be corrected later, new knowledge welcome.

  //it('must not overlap with a pure property', function() {
  //  const obj = {
  //    x: 1,
  //    get x() { return 'ax'; }
  //  };
  //
  //  assert.equal(obj.x, 'ax');
  //});
  //
  //it('multiple `get` for the same property are not allowed', function() {
  //  const obj = {
  //    x: 1,
  //    get x() { return 'ax'; },
  //    get x() { return 'ax1'; }
  //  };
  //
  //  assert.equal(obj.x, 'ax');
  //});
});

<|endoftext|>


<commit_before><commit_msg>Add getting broadcast metrics<commit_after><|endoftext|>


<commit_before><commit_msg>Add promise support for ObjectDB<commit_after><|endoftext|>


<commit_before>module.exports = {
  install,
  uninstall
}

var path = require('path')

function install () {
  if (process.platform === 'darwin') {
    installDarwin()
  }
  if (process.platform === 'win32') {
    installWin32()
  }
  if (process.platform === 'linux') {
    installLinux()
  }
}

function uninstall () {
  if (process.platform === 'darwin') {
    uninstallDarwin()
  }
  if (process.platform === 'win32') {
    uninstallWin32()
  }
  if (process.platform === 'linux') {
    uninstallLinux()
  }
}

function installDarwin () {
  // TODO: Uncomment this once we upgrade past Electron 0.37.4.

  // var electron = require('electron')
  // var app = electron.app

  // // On OS X, only protocols that are listed in Info.plist can be set as the default
  // // handler at runtime.
  // app.setAsDefaultProtocolClient('magnet')

  // // File handlers are registered in the Info.plist.
}

function uninstallDarwin () {}

function installWin32 () {
  var Registry = require('winreg')

  var log = require('./log')

  var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico')

  registerProtocolHandlerWin32('magnet', 'URL:BitTorrent Magnet URL', iconPath, process.execPath)
  registerFileHandlerWin32('.torrent', 'io.webtorrent.torrent', 'BitTorrent Document', iconPath, process.execPath)

  /**
   * To add a protocol handler, the following keys must be added to the Windows registry:
   *
   * HKEY_CLASSES_ROOT
   *   $PROTOCOL
   *     (Default) = "$NAME"
   *     URL Protocol = ""
   *     DefaultIcon
   *       (Default) = "$ICON"
   *     shell
   *       open
   *         command
   *           (Default) = "$COMMAND" "%1"
   *
   * Source: https://msdn.microsoft.com/en-us/library/aa767914.aspx
   *
   * However, the "HKEY_CLASSES_ROOT" key can only be written by the Administrator user.
   * So, we instead write to "HKEY_CURRENT_USER\Software\Classes", which is inherited by
   * "HKEY_CLASSES_ROOT" anyway, and can be written by unprivileged users.
   */

  function registerProtocolHandlerWin32 (protocol, name, icon, command) {
    var protocolKey = new Registry({
      hive: Registry.HKCU, // HKEY_CURRENT_USER
      key: '\\Software\\Classes\\' + protocol
    })

    setProtocol()

    function setProtocol (err) {
      if (err) log.error(err.message)
      protocolKey.set('', Registry.REG_SZ, name, setURLProtocol)
    }

    function setURLProtocol (err) {
      if (err) log.error(err.message)
      protocolKey.set('URL Protocol', Registry.REG_SZ, '', setIcon)
    }

    function setIcon (err) {
      if (err) log.error(err.message)

      var iconKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + protocol + '\\DefaultIcon'
      })
      iconKey.set('', Registry.REG_SZ, icon, setCommand)
    }

    function setCommand (err) {
      if (err) log.error(err.message)

      var commandKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command'
      })
      commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', done)
    }

    function done (err) {
      if (err) log.error(err.message)
    }
  }

  /**
   * To add a file handler, the following keys must be added to the Windows registry:
   *
   * HKEY_CLASSES_ROOT
   *   $EXTENSION
   *     (Default) = "$EXTENSION_ID"
   *   $EXTENSION_ID
   *     (Default) = "$NAME"
   *     DefaultIcon
   *       (Default) = "$ICON"
   *     shell
   *       open
   *         command
   *           (Default) = "$COMMAND" "%1"
   */
  function registerFileHandlerWin32 (ext, id, name, icon, command) {
    setExt()

    function setExt () {
      var extKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + ext
      })
      extKey.set('', Registry.REG_SZ, id, setId)
    }

    function setId (err) {
      if (err) log.error(err.message)

      var idKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + id
      })
      idKey.set('', Registry.REG_SZ, name, setIcon)
    }

    function setIcon (err) {
      if (err) log.error(err.message)

      var iconKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + id + '\\DefaultIcon'
      })
      iconKey.set('', Registry.REG_SZ, icon, setCommand)
    }

    function setCommand (err) {
      if (err) log.error(err.message)

      var commandKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + id + '\\shell\\open\\command'
      })
      commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', done)
    }

    function done (err) {
      if (err) log.error(err.message)
    }
  }
}

function uninstallWin32 () {
  var Registry = require('winreg')

  unregisterProtocolHandlerWin32('magnet', process.execPath)
  unregisterFileHandlerWin32('.torrent', 'io.webtorrent.torrent', process.execPath)

  function unregisterProtocolHandlerWin32 (protocol, command) {
    getCommand()

    function getCommand () {
      var commandKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command'
      })
      commandKey.get('', function (err, item) {
        if (!err && item.value.indexOf(command) >= 0) {
          eraseProtocol()
        }
      })
    }

    function eraseProtocol () {
      var protocolKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + protocol
      })
      protocolKey.erase(function () {})
    }
  }

  function unregisterFileHandlerWin32 (ext, id, command) {
    eraseId()

    function eraseId () {
      var idKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + id
      })
      idKey.erase(getExt)
    }

    function getExt () {
      var extKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + ext
      })
      extKey.get('', function (err, item) {
        if (!err && item.value === id) {
          eraseExt()
        }
      })
    }

    function eraseExt () {
      var extKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + ext
      })
      extKey.erase(function () {})
    }
  }
}

function installLinux () {
  var fs = require('fs')
  var mkdirp = require('mkdirp')
  var os = require('os')
  var path = require('path')

  var config = require('../config')
  var log = require('./log')

  installDesktopFile()
  installIconFile()

  function installDesktopFile () {
    var templatePath = path.join(config.STATIC_PATH, 'linux', 'webtorrent-desktop.desktop')
    fs.readFile(templatePath, 'utf8', writeDesktopFile)
  }

  function writeDesktopFile (err, desktopFile) {
    if (err) return log.error(err.message)

    var appPath = config.IS_PRODUCTION ? path.dirname(process.execPath) : config.ROOT_PATH
    var execPath = process.execPath + (config.IS_PRODUCTION ? '' : ' \.')
    var tryExecPath = process.execPath

    desktopFile = desktopFile.replace(/\$APP_NAME/g, config.APP_NAME)
    desktopFile = desktopFile.replace(/\$APP_PATH/g, appPath)
    desktopFile = desktopFile.replace(/\$EXEC_PATH/g, execPath)
    desktopFile = desktopFile.replace(/\$TRY_EXEC_PATH/g, tryExecPath)

    var desktopFilePath = path.join(
      os.homedir(),
      '.local',
      'share',
      'applications',
      'webtorrent-desktop.desktop'
    )
    mkdirp(path.dirname(desktopFilePath))
    fs.writeFile(desktopFilePath, desktopFile, function (err) {
      if (err) return log.error(err.message)
    })
  }

  function installIconFile () {
    var iconStaticPath = path.join(config.STATIC_PATH, 'WebTorrent.png')
    fs.readFile(iconStaticPath, writeIconFile)
  }

  function writeIconFile (err, iconFile) {
    if (err) return log.error(err.message)

    var iconFilePath = path.join(
      os.homedir(),
      '.local',
      'share',
      'icons',
      'webtorrent-desktop.png'
    )
    mkdirp(path.dirname(iconFilePath))
    fs.writeFile(iconFilePath, iconFile, function (err) {
      if (err) return log.error(err.message)
    })
  }
}

function uninstallLinux () {
  var os = require('os')
  var path = require('path')
  var rimraf = require('rimraf')

  var desktopFilePath = path.join(
    os.homedir(),
    '.local',
    'share',
    'applications',
    'webtorrent-desktop.desktop'
  )
  rimraf.sync(desktopFilePath)

  var iconFilePath = path.join(
    os.homedir(),
    '.local',
    'share',
    'icons',
    'webtorrent-desktop.png'
  )
  rimraf.sync(iconFilePath)
}
<commit_msg>Revert "TEMPORARY: Comment out code that requires Electron 0.37.4"<commit_after>module.exports = {
  install,
  uninstall
}

var path = require('path')

function install () {
  if (process.platform === 'darwin') {
    installDarwin()
  }
  if (process.platform === 'win32') {
    installWin32()
  }
  if (process.platform === 'linux') {
    installLinux()
  }
}

function uninstall () {
  if (process.platform === 'darwin') {
    uninstallDarwin()
  }
  if (process.platform === 'win32') {
    uninstallWin32()
  }
  if (process.platform === 'linux') {
    uninstallLinux()
  }
}

function installDarwin () {
  var electron = require('electron')
  var app = electron.app

  // On OS X, only protocols that are listed in Info.plist can be set as the default
  // handler at runtime.
  app.setAsDefaultProtocolClient('magnet')

  // File handlers are registered in the Info.plist.
}

function uninstallDarwin () {}

function installWin32 () {
  var Registry = require('winreg')

  var log = require('./log')

  var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico')

  registerProtocolHandlerWin32('magnet', 'URL:BitTorrent Magnet URL', iconPath, process.execPath)
  registerFileHandlerWin32('.torrent', 'io.webtorrent.torrent', 'BitTorrent Document', iconPath, process.execPath)

  /**
   * To add a protocol handler, the following keys must be added to the Windows registry:
   *
   * HKEY_CLASSES_ROOT
   *   $PROTOCOL
   *     (Default) = "$NAME"
   *     URL Protocol = ""
   *     DefaultIcon
   *       (Default) = "$ICON"
   *     shell
   *       open
   *         command
   *           (Default) = "$COMMAND" "%1"
   *
   * Source: https://msdn.microsoft.com/en-us/library/aa767914.aspx
   *
   * However, the "HKEY_CLASSES_ROOT" key can only be written by the Administrator user.
   * So, we instead write to "HKEY_CURRENT_USER\Software\Classes", which is inherited by
   * "HKEY_CLASSES_ROOT" anyway, and can be written by unprivileged users.
   */

  function registerProtocolHandlerWin32 (protocol, name, icon, command) {
    var protocolKey = new Registry({
      hive: Registry.HKCU, // HKEY_CURRENT_USER
      key: '\\Software\\Classes\\' + protocol
    })

    setProtocol()

    function setProtocol (err) {
      if (err) log.error(err.message)
      protocolKey.set('', Registry.REG_SZ, name, setURLProtocol)
    }

    function setURLProtocol (err) {
      if (err) log.error(err.message)
      protocolKey.set('URL Protocol', Registry.REG_SZ, '', setIcon)
    }

    function setIcon (err) {
      if (err) log.error(err.message)

      var iconKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + protocol + '\\DefaultIcon'
      })
      iconKey.set('', Registry.REG_SZ, icon, setCommand)
    }

    function setCommand (err) {
      if (err) log.error(err.message)

      var commandKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command'
      })
      commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', done)
    }

    function done (err) {
      if (err) log.error(err.message)
    }
  }

  /**
   * To add a file handler, the following keys must be added to the Windows registry:
   *
   * HKEY_CLASSES_ROOT
   *   $EXTENSION
   *     (Default) = "$EXTENSION_ID"
   *   $EXTENSION_ID
   *     (Default) = "$NAME"
   *     DefaultIcon
   *       (Default) = "$ICON"
   *     shell
   *       open
   *         command
   *           (Default) = "$COMMAND" "%1"
   */
  function registerFileHandlerWin32 (ext, id, name, icon, command) {
    setExt()

    function setExt () {
      var extKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + ext
      })
      extKey.set('', Registry.REG_SZ, id, setId)
    }

    function setId (err) {
      if (err) log.error(err.message)

      var idKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + id
      })
      idKey.set('', Registry.REG_SZ, name, setIcon)
    }

    function setIcon (err) {
      if (err) log.error(err.message)

      var iconKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + id + '\\DefaultIcon'
      })
      iconKey.set('', Registry.REG_SZ, icon, setCommand)
    }

    function setCommand (err) {
      if (err) log.error(err.message)

      var commandKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + id + '\\shell\\open\\command'
      })
      commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', done)
    }

    function done (err) {
      if (err) log.error(err.message)
    }
  }
}

function uninstallWin32 () {
  var Registry = require('winreg')

  unregisterProtocolHandlerWin32('magnet', process.execPath)
  unregisterFileHandlerWin32('.torrent', 'io.webtorrent.torrent', process.execPath)

  function unregisterProtocolHandlerWin32 (protocol, command) {
    getCommand()

    function getCommand () {
      var commandKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command'
      })
      commandKey.get('', function (err, item) {
        if (!err && item.value.indexOf(command) >= 0) {
          eraseProtocol()
        }
      })
    }

    function eraseProtocol () {
      var protocolKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + protocol
      })
      protocolKey.erase(function () {})
    }
  }

  function unregisterFileHandlerWin32 (ext, id, command) {
    eraseId()

    function eraseId () {
      var idKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + id
      })
      idKey.erase(getExt)
    }

    function getExt () {
      var extKey = new Registry({
        hive: Registry.HKCU,
        key: '\\Software\\Classes\\' + ext
      })
      extKey.get('', function (err, item) {
        if (!err && item.value === id) {
          eraseExt()
        }
      })
    }

    function eraseExt () {
      var extKey = new Registry({
        hive: Registry.HKCU, // HKEY_CURRENT_USER
        key: '\\Software\\Classes\\' + ext
      })
      extKey.erase(function () {})
    }
  }
}

function installLinux () {
  var fs = require('fs')
  var mkdirp = require('mkdirp')
  var os = require('os')
  var path = require('path')

  var config = require('../config')
  var log = require('./log')

  installDesktopFile()
  installIconFile()

  function installDesktopFile () {
    var templatePath = path.join(config.STATIC_PATH, 'linux', 'webtorrent-desktop.desktop')
    fs.readFile(templatePath, 'utf8', writeDesktopFile)
  }

  function writeDesktopFile (err, desktopFile) {
    if (err) return log.error(err.message)

    var appPath = config.IS_PRODUCTION ? path.dirname(process.execPath) : config.ROOT_PATH
    var execPath = process.execPath + (config.IS_PRODUCTION ? '' : ' \.')
    var tryExecPath = process.execPath

    desktopFile = desktopFile.replace(/\$APP_NAME/g, config.APP_NAME)
    desktopFile = desktopFile.replace(/\$APP_PATH/g, appPath)
    desktopFile = desktopFile.replace(/\$EXEC_PATH/g, execPath)
    desktopFile = desktopFile.replace(/\$TRY_EXEC_PATH/g, tryExecPath)

    var desktopFilePath = path.join(
      os.homedir(),
      '.local',
      'share',
      'applications',
      'webtorrent-desktop.desktop'
    )
    mkdirp(path.dirname(desktopFilePath))
    fs.writeFile(desktopFilePath, desktopFile, function (err) {
      if (err) return log.error(err.message)
    })
  }

  function installIconFile () {
    var iconStaticPath = path.join(config.STATIC_PATH, 'WebTorrent.png')
    fs.readFile(iconStaticPath, writeIconFile)
  }

  function writeIconFile (err, iconFile) {
    if (err) return log.error(err.message)

    var iconFilePath = path.join(
      os.homedir(),
      '.local',
      'share',
      'icons',
      'webtorrent-desktop.png'
    )
    mkdirp(path.dirname(iconFilePath))
    fs.writeFile(iconFilePath, iconFile, function (err) {
      if (err) return log.error(err.message)
    })
  }
}

function uninstallLinux () {
  var os = require('os')
  var path = require('path')
  var rimraf = require('rimraf')

  var desktopFilePath = path.join(
    os.homedir(),
    '.local',
    'share',
    'applications',
    'webtorrent-desktop.desktop'
  )
  rimraf.sync(desktopFilePath)

  var iconFilePath = path.join(
    os.homedir(),
    '.local',
    'share',
    'icons',
    'webtorrent-desktop.png'
  )
  rimraf.sync(iconFilePath)
}
<|endoftext|>