<commit_before>define(function () {
  return function (ParsleyValidator) {
    describe('ParsleyValidator', function () {
      var parsleyValidator = new ParsleyValidator(window.ParsleyConfig.validators || {}, window.ParsleyConfig.i18n || {});

      it('should be a function', function () {
        expect(ParsleyValidator).to.be.a('function');
      });
      it('should bind global config validators if given in constructor', function () {
        $.extend(true, window.ParsleyConfig, {
          validators: {
            foo: { fn: function () {}, priority: 42 },
            bar: { fn: function () {}, priority: 12 }
          }
        });
        var parsleyValidator = new ParsleyValidator(window.ParsleyConfig.validators);
        expect(parsleyValidator.validators).to.have.key('foo');
        expect(parsleyValidator.validators).to.have.key('bar');
        delete window.ParsleyConfig.validators.foo;
        delete window.ParsleyConfig.validators.bar;
      });
      it('should have a required validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.required())).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.required())).to.be(true);
      });
      it('should have a notblank validator', function () {
        expect(parsleyValidator.validate(' ', parsleyValidator.validators.notblank())).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.notblank())).to.be(true);
      });
      it('should have a type="email" validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.type('email'))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('email'))).not.to.be(true);
        expect(parsleyValidator.validate('foo@bar.baz', parsleyValidator.validators.type('email'))).to.be(true);
        expect(parsleyValidator.validate('foo+bar@bar.baz', parsleyValidator.validators.type('email'))).to.be(true);
        expect(parsleyValidator.validate('foo.bar@bar.baz', parsleyValidator.validators.type('email'))).to.be(true);
        expect(parsleyValidator.validate('foo.bar@bar.com.ext', parsleyValidator.validators.type('email'))).to.be(true);
      });
      it('should have a min validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.min(6))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.min(6))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.min(6))).not.to.be(true);
        expect(parsleyValidator.validate('6', parsleyValidator.validators.min(6))).to.be(true);
        expect(parsleyValidator.validate('10', parsleyValidator.validators.min(6))).to.be(true);
        $('body').append('<input type="text" id="element" value="7" min="2" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a max validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.max(10))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.max(10))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.max(10))).to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.max("10"))).to.be(true);
        expect(parsleyValidator.validate('10', parsleyValidator.validators.max(10))).to.be(true);
        expect(parsleyValidator.validate('17', parsleyValidator.validators.max(10))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="7" max="20" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a range validator', function () {
        expect(parsleyValidator.validate('1', parsleyValidator.validators.range([5, 10]))).not.to.be(true);
        expect(parsleyValidator.validate('7', parsleyValidator.validators.range([5, 10]))).to.be(true);
        expect(parsleyValidator.validate('17', parsleyValidator.validators.range([5, 10]))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="7" max="20" min="2" />');
        expect($('#element').parsley().isValid()).to.be(true);

        $('#element').remove();
        $('body').append('<input type="range" id="element" value="7" max="20" min="2" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a type="number" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('number'))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.type('number'))).to.be(true);
        expect(parsleyValidator.validate('1.5', parsleyValidator.validators.type('number'))).to.be(true);
        expect(parsleyValidator.validate('-1.5', parsleyValidator.validators.type('number'))).to.be(true);
        expect(parsleyValidator.validate('1,500.642', parsleyValidator.validators.type('number'))).to.be(true);
      });
      it('should have a type="digits" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.type('digits'))).to.be(true);
        expect(parsleyValidator.validate('-1', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('1.5', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('-1.5', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('1,500.642', parsleyValidator.validators.type('digits'))).not.to.be(true);
      });
      it('should have a type="integer" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('integer'))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.type('integer'))).to.be(true);
        expect(parsleyValidator.validate('-1', parsleyValidator.validators.type('integer'))).to.be(true);
        expect(parsleyValidator.validate('1.5', parsleyValidator.validators.type('integer'))).not.to.be(true);
        expect(parsleyValidator.validate('-1.5', parsleyValidator.validators.type('integer'))).not.to.be(true);
      });
      it('should have a type="alphanum" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('alphanum'))).to.be(true);
        expect(parsleyValidator.validate('foo bar', parsleyValidator.validators.type('alphanum'))).not.to.be(true);
        expect(parsleyValidator.validate('foo$', parsleyValidator.validators.type('alphanum'))).not.to.be(true);
        $('body').append('<input data-parsley-type="alphanum" id="element" value="v4kRRyhYvo0P" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a type="url" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('url'))).not.to.be(true);
        expect(parsleyValidator.validate('foo bar', parsleyValidator.validators.type('url'))).not.to.be(true);
        expect(parsleyValidator.validate('http://', parsleyValidator.validators.type('url'))).not.to.be(true);
        expect(parsleyValidator.validate('foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('www.foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('http://www.foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('https://www.foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('http://192.168.1.1/foo/bar', parsleyValidator.validators.type('url'))).to.be(true);
      });
      it('should have a pattern validator', function () {
        expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('[a-z]+'))).to.be(true);
        expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('[a-z]+'))).not.to.be(true);
        expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('/[a-z]+/'))).to.be(true);
        expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('/[a-z]+/'))).not.to.be(true);
        expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('/[a-z]+/i'))).to.be(true);
        expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('/[a-z]+/i'))).to.be(true);
      });
      it('should have a length validator', function () {
        expect(parsleyValidator.validate('foobar', parsleyValidator.validators.length([3, 9]))).to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.length([4, 9]))).not.to.be(true);
        expect(parsleyValidator.validate('foobarbaz', parsleyValidator.validators.length([3, 8]))).not.to.be(true);
      });
      it('should have a minlength validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.minlength(3))).to.be(true);
        expect(parsleyValidator.validate('fo', parsleyValidator.validators.minlength(3))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="foo" data-parsley-minlength="2" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a maxlength validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.maxlength(3))).to.be(true);
        expect(parsleyValidator.validate('foobar', parsleyValidator.validators.maxlength(3))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="foo" data-parsley-maxlength="10" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a check validator', function () {
        expect(parsleyValidator.validate(['foo', 'bar', 'baz'], parsleyValidator.validators.check([3, 5]))).to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar', 'baz', 'qux', 'bux'], parsleyValidator.validators.check([3, 4]))).not.to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar'], parsleyValidator.validators.check([3, 5]))).not.to.be(true);
      });
      it('should have a mincheck validator', function () {
        expect(parsleyValidator.validate(['foo', 'bar', 'baz'], parsleyValidator.validators.mincheck(3))).to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar'], parsleyValidator.validators.mincheck(3))).not.to.be(true);
      });
      it('should have a maxcheck validator', function () {
        expect(parsleyValidator.validate(['foo', 'bar', 'baz'], parsleyValidator.validators.maxcheck(3))).to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar', 'baz', 'qux'], parsleyValidator.validators.maxcheck(3))).not.to.be(true);
      });
      it('should have an equalto validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.equalto('foo'))).not.to.be(true);
        expect(parsleyValidator.validate('bar', parsleyValidator.validators.equalto('foo'))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.equalto('foo'))).to.be(true);
        $('body').append('<input type="text" id="element" data-parsley-equalto="#equalto" required /><input type="text" id="equalto" value="foo" />');
        expect($('#element').psly().isValid()).to.be(false);
        $('#element').val('fo');
        expect($('#element').psly().isValid()).to.be(false);
        $('#element').val('foo');
        expect($('#element').psly().isValid()).to.be(true);
        $('#equalto').remove();
      });
      it('should handle proper error message for validators', function () {
        expect(parsleyValidator.getErrorMessage({ name: 'length', requirements: [3, 6] })).to.be('This value length is invalid. It should be between 3 and 6 characters long.');
        expect(parsleyValidator.getErrorMessage({ name: 'notexisting' })).to.be('This value seems to be invalid.');
      });
      it('should handle proper error message for validators in various languages', function () {
        parsleyValidator.setLocale('fr');
        expect(parsleyValidator.getErrorMessage({ name: 'length', requirements: [3, 6] })).to.be('Cette valeur doit contenir entre 3 et 6 caractères.');
        expect(parsleyValidator.getErrorMessage({ name: 'notexisting' })).to.be('Cette valeur semble non valide.');
      });

      it('should not break for an incomplete language', function () {
        parsleyValidator.addCatalog('klingon', {}, true);
        expect(parsleyValidator.getErrorMessage({ name: 'type', requirements: 'email' })).to.be('This value seems to be invalid.');
        expect(parsleyValidator.getErrorMessage({ name: 'length', requirements: [3, 6] })).to.be('This value seems to be invalid.');
      });

      it('should handle parametersTransformer for custom validators', function () {
        parsleyValidator.addValidator('foo', function (requirements) {
          return requirements;
        }, 32, function (requirements) {
          return { req: requirements };
        });
        expect(parsleyValidator.validators.foo().requirementsTransformer).to.be.a('function');
        parsleyValidator.updateValidator('foo', function (requirements) {
          return requirements;
        }, 32);
        expect(parsleyValidator.validators.foo().requirementsTransformer).to.be(undefined);
        parsleyValidator.removeValidator('foo');
        expect(parsleyValidator.validators.foo).to.be(undefined);
      });
      afterEach(function () {
        $('#element').remove();
      });
    });
  };
});
<commit_msg>Rename local var<commit_after>define(function () {
  return function (ParsleyValidator) {
    describe('ParsleyValidator', function () {
      var parsleyValidator = new ParsleyValidator(window.ParsleyConfig.validators || {}, window.ParsleyConfig.i18n || {});

      it('should be a function', function () {
        expect(ParsleyValidator).to.be.a('function');
      });
      it('should bind global config validators if given in constructor', function () {
        $.extend(true, window.ParsleyConfig, {
          validators: {
            foo: { fn: function () {}, priority: 42 },
            bar: { fn: function () {}, priority: 12 }
          }
        });
        var validator = new ParsleyValidator(window.ParsleyConfig.validators);
        expect(validator.validators).to.have.key('foo');
        expect(validator.validators).to.have.key('bar');
        delete window.ParsleyConfig.validators.foo;
        delete window.ParsleyConfig.validators.bar;
      });
      it('should have a required validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.required())).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.required())).to.be(true);
      });
      it('should have a notblank validator', function () {
        expect(parsleyValidator.validate(' ', parsleyValidator.validators.notblank())).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.notblank())).to.be(true);
      });
      it('should have a type="email" validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.type('email'))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('email'))).not.to.be(true);
        expect(parsleyValidator.validate('foo@bar.baz', parsleyValidator.validators.type('email'))).to.be(true);
        expect(parsleyValidator.validate('foo+bar@bar.baz', parsleyValidator.validators.type('email'))).to.be(true);
        expect(parsleyValidator.validate('foo.bar@bar.baz', parsleyValidator.validators.type('email'))).to.be(true);
        expect(parsleyValidator.validate('foo.bar@bar.com.ext', parsleyValidator.validators.type('email'))).to.be(true);
      });
      it('should have a min validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.min(6))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.min(6))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.min(6))).not.to.be(true);
        expect(parsleyValidator.validate('6', parsleyValidator.validators.min(6))).to.be(true);
        expect(parsleyValidator.validate('10', parsleyValidator.validators.min(6))).to.be(true);
        $('body').append('<input type="text" id="element" value="7" min="2" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a max validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.max(10))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.max(10))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.max(10))).to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.max("10"))).to.be(true);
        expect(parsleyValidator.validate('10', parsleyValidator.validators.max(10))).to.be(true);
        expect(parsleyValidator.validate('17', parsleyValidator.validators.max(10))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="7" max="20" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a range validator', function () {
        expect(parsleyValidator.validate('1', parsleyValidator.validators.range([5, 10]))).not.to.be(true);
        expect(parsleyValidator.validate('7', parsleyValidator.validators.range([5, 10]))).to.be(true);
        expect(parsleyValidator.validate('17', parsleyValidator.validators.range([5, 10]))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="7" max="20" min="2" />');
        expect($('#element').parsley().isValid()).to.be(true);

        $('#element').remove();
        $('body').append('<input type="range" id="element" value="7" max="20" min="2" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a type="number" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('number'))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.type('number'))).to.be(true);
        expect(parsleyValidator.validate('1.5', parsleyValidator.validators.type('number'))).to.be(true);
        expect(parsleyValidator.validate('-1.5', parsleyValidator.validators.type('number'))).to.be(true);
        expect(parsleyValidator.validate('1,500.642', parsleyValidator.validators.type('number'))).to.be(true);
      });
      it('should have a type="digits" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.type('digits'))).to.be(true);
        expect(parsleyValidator.validate('-1', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('1.5', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('-1.5', parsleyValidator.validators.type('digits'))).not.to.be(true);
        expect(parsleyValidator.validate('1,500.642', parsleyValidator.validators.type('digits'))).not.to.be(true);
      });
      it('should have a type="integer" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('integer'))).not.to.be(true);
        expect(parsleyValidator.validate('1', parsleyValidator.validators.type('integer'))).to.be(true);
        expect(parsleyValidator.validate('-1', parsleyValidator.validators.type('integer'))).to.be(true);
        expect(parsleyValidator.validate('1.5', parsleyValidator.validators.type('integer'))).not.to.be(true);
        expect(parsleyValidator.validate('-1.5', parsleyValidator.validators.type('integer'))).not.to.be(true);
      });
      it('should have a type="alphanum" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('alphanum'))).to.be(true);
        expect(parsleyValidator.validate('foo bar', parsleyValidator.validators.type('alphanum'))).not.to.be(true);
        expect(parsleyValidator.validate('foo$', parsleyValidator.validators.type('alphanum'))).not.to.be(true);
        $('body').append('<input data-parsley-type="alphanum" id="element" value="v4kRRyhYvo0P" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a type="url" validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.type('url'))).not.to.be(true);
        expect(parsleyValidator.validate('foo bar', parsleyValidator.validators.type('url'))).not.to.be(true);
        expect(parsleyValidator.validate('http://', parsleyValidator.validators.type('url'))).not.to.be(true);
        expect(parsleyValidator.validate('foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('www.foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('http://www.foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('https://www.foo.bar', parsleyValidator.validators.type('url'))).to.be(true);
        expect(parsleyValidator.validate('http://192.168.1.1/foo/bar', parsleyValidator.validators.type('url'))).to.be(true);
      });
      it('should have a pattern validator', function () {
        expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('[a-z]+'))).to.be(true);
        expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('[a-z]+'))).not.to.be(true);
        expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('/[a-z]+/'))).to.be(true);
        expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('/[a-z]+/'))).not.to.be(true);
        expect(parsleyValidator.validate('a', parsleyValidator.validators.pattern('/[a-z]+/i'))).to.be(true);
        expect(parsleyValidator.validate('A', parsleyValidator.validators.pattern('/[a-z]+/i'))).to.be(true);
      });
      it('should have a length validator', function () {
        expect(parsleyValidator.validate('foobar', parsleyValidator.validators.length([3, 9]))).to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.length([4, 9]))).not.to.be(true);
        expect(parsleyValidator.validate('foobarbaz', parsleyValidator.validators.length([3, 8]))).not.to.be(true);
      });
      it('should have a minlength validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.minlength(3))).to.be(true);
        expect(parsleyValidator.validate('fo', parsleyValidator.validators.minlength(3))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="foo" data-parsley-minlength="2" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a maxlength validator', function () {
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.maxlength(3))).to.be(true);
        expect(parsleyValidator.validate('foobar', parsleyValidator.validators.maxlength(3))).not.to.be(true);
        $('body').append('<input type="text" id="element" value="foo" data-parsley-maxlength="10" />');
        expect($('#element').parsley().isValid()).to.be(true);
      });
      it('should have a check validator', function () {
        expect(parsleyValidator.validate(['foo', 'bar', 'baz'], parsleyValidator.validators.check([3, 5]))).to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar', 'baz', 'qux', 'bux'], parsleyValidator.validators.check([3, 4]))).not.to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar'], parsleyValidator.validators.check([3, 5]))).not.to.be(true);
      });
      it('should have a mincheck validator', function () {
        expect(parsleyValidator.validate(['foo', 'bar', 'baz'], parsleyValidator.validators.mincheck(3))).to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar'], parsleyValidator.validators.mincheck(3))).not.to.be(true);
      });
      it('should have a maxcheck validator', function () {
        expect(parsleyValidator.validate(['foo', 'bar', 'baz'], parsleyValidator.validators.maxcheck(3))).to.be(true);
        expect(parsleyValidator.validate(['foo', 'bar', 'baz', 'qux'], parsleyValidator.validators.maxcheck(3))).not.to.be(true);
      });
      it('should have an equalto validator', function () {
        expect(parsleyValidator.validate('', parsleyValidator.validators.equalto('foo'))).not.to.be(true);
        expect(parsleyValidator.validate('bar', parsleyValidator.validators.equalto('foo'))).not.to.be(true);
        expect(parsleyValidator.validate('foo', parsleyValidator.validators.equalto('foo'))).to.be(true);
        $('body').append('<input type="text" id="element" data-parsley-equalto="#equalto" required /><input type="text" id="equalto" value="foo" />');
        expect($('#element').psly().isValid()).to.be(false);
        $('#element').val('fo');
        expect($('#element').psly().isValid()).to.be(false);
        $('#element').val('foo');
        expect($('#element').psly().isValid()).to.be(true);
        $('#equalto').remove();
      });
      it('should handle proper error message for validators', function () {
        expect(parsleyValidator.getErrorMessage({ name: 'length', requirements: [3, 6] })).to.be('This value length is invalid. It should be between 3 and 6 characters long.');
        expect(parsleyValidator.getErrorMessage({ name: 'notexisting' })).to.be('This value seems to be invalid.');
      });
      it('should handle proper error message for validators in various languages', function () {
        parsleyValidator.setLocale('fr');
        expect(parsleyValidator.getErrorMessage({ name: 'length', requirements: [3, 6] })).to.be('Cette valeur doit contenir entre 3 et 6 caractères.');
        expect(parsleyValidator.getErrorMessage({ name: 'notexisting' })).to.be('Cette valeur semble non valide.');
      });

      it('should not break for an incomplete language', function () {
        parsleyValidator.addCatalog('klingon', {}, true);
        expect(parsleyValidator.getErrorMessage({ name: 'type', requirements: 'email' })).to.be('This value seems to be invalid.');
        expect(parsleyValidator.getErrorMessage({ name: 'length', requirements: [3, 6] })).to.be('This value seems to be invalid.');
      });

      it('should handle parametersTransformer for custom validators', function () {
        parsleyValidator.addValidator('foo', function (requirements) {
          return requirements;
        }, 32, function (requirements) {
          return { req: requirements };
        });
        expect(parsleyValidator.validators.foo().requirementsTransformer).to.be.a('function');
        parsleyValidator.updateValidator('foo', function (requirements) {
          return requirements;
        }, 32);
        expect(parsleyValidator.validators.foo().requirementsTransformer).to.be(undefined);
        parsleyValidator.removeValidator('foo');
        expect(parsleyValidator.validators.foo).to.be(undefined);
      });
      afterEach(function () {
        $('#element').remove();
      });
    });
  };
});
<|endoftext|>


<commit_before>/*
 * Evennia webclient library. Load this into your <head> html page
 * template with
 *
 * <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
 * <script webclient/js/evennia.js</script>
 *
 * In your template you can then put elements with specific ids that
 * evennia will look for.  Evennia will via this library relay text to
 * specific divs if given, or to the "text" div if not.
 *
 */

/*
 * global vars
 */
var websocket;

/*
 * Configuration variables
 * (set by the user)
 */

var echo_to_textarea = true;

/*
 * Evennia OOB command map; this holds custom js functions
 * that the OOB handler supports. Each key is the name
 * of a js callback function. External development is
 * done by adding functions func(data) to this object,
 * where data is the data object sent from the server.
 */

oob_commands = {
    "text": function(data) {
        // basic div redistributor making
        // use of the default text relay.
        // Use in combination with the
        // divclass oob argument to send
        // text to different DOM element classes.
        var msg = data.text;
        var divclass = data.divclass;
        toClass(divclass, msg);
    }
};

/*
 * Send text to given element class
 */
toClass = function(divclass, data) {
    // loop over all objects of divclass
    //console.log("toClass: " + divclass + " " + data);
    $("." + divclass).each(function() {
        switch (divclass) {
            case "textarea":
                // update the bottom of the normal text area
                // and scroll said area.
                var oldtext = $.trim($(this).val());
                $(this).val(oldtext + "\n" + data);
                $(this).scrollTop($(this)[0].scrollHeight);
                break;
            case "lookarea":
                // update the look text box
                $(this).val($.trim(data));
                break;
        }
    });
}

/*
 * Send data to Evennia. This data is always sent
 * as an JSON object. {key:arg, ...}
 *    key "cmd" - a text input command (in arg)
 *    other keys - interpreted as OOB command keys and their args
 *                 (can be an array)
 */
dataSend = function(classname, data) {
    // client -> Evennia.
    var outdata = {classname: data}; // for testing
    //websocket.send(JSON.stringify(data)) // send to Evennia
}

/*
 * Data coming from Evennia to client. This data
 * is always on the form of a JSON object {key:arg}
 */
dataRecv = function(event) {
    // Evennia -> client
    var data = JSON.parse(event.data);

    // send to be printed in element class
    for (var cmdname in data) {
        if (data.hasOwnProperty(cmdname) &&  cmdname in oob_commands) {
            try {
                oob_commands[cmdname](data);
            }
            catch(error) {
                alert("Crash in function " + cmdname + "(data): " + error);
            }
        }
    }
}

/*
 * Input history objects
 */

historyObj = function () {
    // history object storage
    return {"current": undefined, // save the current input
            "hpos": 0,   // position in history
            "store": []}   // history steore
}
addHistory = function(obj, lastentry) {
    // Add text to the history
    if (!obj.hasOwnProperty("input_history")) {
        // create a new history object
        obj.input_history = new historyObj();
    }
    if (lastentry && obj.input_history.store && obj.input_history.store[0] != lastentry) {
        // don't store duplicates.
        obj.input_history.store.unshift(lastentry);
        obj.input_history.hpos = -1;
        obj.input_history.current = undefined;
    }
}
getHistory = function(obj, lastentry, step) {
    // step +1 or -1 in history
    if (!obj.hasOwnProperty("input_history")) {
        // create a new history object
        obj.input_history = new historyObj();
    }
    var history = obj.input_history;
    var lhist = history.store.length;
    var hpos = history.hpos + step;

    if (typeof(obj.input_history.current) === "undefined") {
        obj.input_history.current = lastentry;
    }
    if (hpos < 0) {
        // get the current but remove the cached one so it
        // can be replaced.
        obj.input_history.hpos = -1;
        var current = obj.input_history.current;
        obj.input_history.current = undefined;
        return current;
    }
    hpos = Math.max(0, Math.min(hpos, lhist-1));
    //console.log("lhist: " + lhist + " hpos: " + hpos + " current: " + obj.input_history.current);
    obj.input_history.hpos = hpos;
    return history.store[hpos];
}

/*
 * Initialization
 */

initialize = function() {

    // register events

    // single line input
    $(".input_singleline").on("submit", function(event) {
        // input from the single-line input field
        event.preventDefault(); // stop form from switching page
        var field = $(this).find("input");
        var msg = field.val();
        addHistory(this, msg);
        field.val("");
        dataSend("inputfield", msg);
        if (echo_to_textarea) {
            // echo to textfield
            toClass("textarea", msg);
            toClass("lookarea", msg);
            toClass("listarea", msg);
        }
    });

    $(".input_singleline :input").on("keyup", function(event) {
        switch (event.keyCode) {
            case 13: // Enter
                event.preventDefault();
                $(this).trigger("submit");
                break
            case 38: // Up
                event.preventDefault();
                var lastentry = $(this).val();
                var hist = getHistory(this.form, lastentry, 1);
                if (hist) $(this).val(hist);
                break
            case 40: // Down
                event.preventDefault();
                var lastentry = $(this).val();
                var hist = getHistory(this.form, lastentry, -1);
                if (hist) $(this).val(hist);
                break
            default:
        }
    });

    // textarea input

    $(".input_multiline").on("submit", function(event) {
        // input from the textarea input
        event.preventDefault(); // stop form from switching page
        var field = $(this).find("textarea");
        var msg = field.val();
        addHistory(this, msg);
        field.val("");
        dataSend("inputfield", msg);
        if (echo_to_textarea) {
            // echo to textfield
            toClass("textarea", msg);
            toClass("lookarea", msg);
            toClass("listarea", msg);
        }
    });

    $(".input_multiline :input").on("keyup", function(event) {
        // Ctrl + <key> commands
        if (event.ctrlKey) {
            switch (event.keyCode) {
                case 13: // Ctrl + Enter
                    event.preventDefault();
                    $(this).trigger("submit");
                    break
                case 38: // Ctrl + Up
                    event.preventDefault();
                    var lastentry = $(this).val();
                    var hist = getHistory(this.form, lastentry, 1);
                    if (hist) $(this).val(hist);
                    break
                case 40: // Ctrl + Down
                    event.preventDefault();
                    var lastentry = $(this).val();
                    var hist = getHistory(this.form, lastentry, -1);
                    if (hist) $(this).val(hist);
                    break
                default:
            }
        }
    });

    // make sure textarea fills surrounding div
    //$('textarea').css({height:(300-$('form').height())+'px'});
    //$('textarea').css({height:"inherit", resize:"vertical"});

    // configurations
    $(".echo").on("change", function(event) {
        // configure echo on/off checkbox button
        event.preventDefault();
        echo_to_textarea = $(this).prop("checked");
    });

    // initialize the websocket connection
    //websocket = new WebSocket(wsurl);
    //websocket.onopen = function(event) {};
    //websocket.onclose = function(event) {};
    //websocket.onerror = function(event) {};
    //websocket.onmessage = dataOut;

}

/*
 * Kick system into gear first when
 * the document has loaded fully.
 */

$(document).ready(function() {
    // a small timeout to stop 'loading' indicator in Chrome
    setTimeout(function () {
        initialize();
    }, 500);
    // set an idle timer to avoid proxy servers to time out on us (every 3 minutes)
    setInterval(function() {
        dataSend("textinput", "idle");
    }, 60000*3);
});

<commit_msg>Updated js version for better css (not currently working though<commit_after>/*
 * Evennia webclient library. Load this into your <head> html page
 * template with
 *
 * <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
 * <script webclient/js/evennia.js</script>
 *
 * In your template you can then put elements with specific ids that
 * evennia will look for.  Evennia will via this library relay text to
 * specific divs if given, or to the "text" div if not.
 *
 */

/*
 * global vars
 */
var websocket;

/*
 * Configuration variables
 * (set by the user)
 */

var echo_to_textarea = true;

/*
 * Evennia OOB command map; this holds custom js functions
 * that the OOB handler supports. Each key is the name
 * of a js callback function. External development is
 * done by adding functions func(data) to this object,
 * where data is the data object sent from the server.
 */

oob_commands = {
    "text": function(data) {
        // basic div redistributor making
        // use of the default text relay.
        // Use in combination with the
        // divclass oob argument to send
        // text to different DOM element classes.
        var msg = data.text;
        var divclass = data.divclass;
        toClass(divclass, msg);
    }
};

/*
 * Send text to given element class
 */
toClass = function(divclass, data) {
    // loop over all objects of divclass
    //console.log("toClass: " + divclass + " " + data);
    $("." + divclass).each(function() {
        switch (divclass) {
            case "textoutput":
                // update the bottom of the normal text area
                // and scroll said area.
                var oldtext = $.trim($(this).val());
                $(this).val(oldtext + "\n" + data);
                //$(this).scrollTop($(this)[0].scrollHeight);
                break;
            case "lookoutput":
                // update the look text box
                $(this).val(data);
                break;
        }
    });
}

/*
 * Send data to Evennia. This data is always sent
 * as an JSON object. {key:arg, ...}
 *    key "cmd" - a text input command (in arg)
 *    other keys - interpreted as OOB command keys and their args
 *                 (can be an array)
 */
dataSend = function(classname, data) {
    // client -> Evennia.
    var outdata = {classname: data}; // for testing
    //websocket.send(JSON.stringify(data)) // send to Evennia
}

/*
 * Data coming from Evennia to client. This data
 * is always on the form of a JSON object {key:arg}
 */
dataRecv = function(event) {
    // Evennia -> client
    var data = JSON.parse(event.data);

    // send to be printed in element class
    for (var cmdname in data) {
        if (data.hasOwnProperty(cmdname) &&  cmdname in oob_commands) {
            try {
                oob_commands[cmdname](data);
            }
            catch(error) {
                alert("Crash in function " + cmdname + "(data): " + error);
            }
        }
    }
}

/*
 * Input history objects
 */

historyObj = function () {
    // history object storage
    return {"current": undefined, // save the current input
            "hpos": 0,   // position in history
            "store": []}   // history steore
}
addHistory = function(obj, lastentry) {
    // Add text to the history
    if (!obj.hasOwnProperty("input_history")) {
        // create a new history object
        obj.input_history = new historyObj();
    }
    if (lastentry && obj.input_history.store && obj.input_history.store[0] != lastentry) {
        // don't store duplicates.
        obj.input_history.store.unshift(lastentry);
        obj.input_history.hpos = -1;
        obj.input_history.current = undefined;
    }
}
getHistory = function(obj, lastentry, step) {
    // step +1 or -1 in history
    if (!obj.hasOwnProperty("input_history")) {
        // create a new history object
        obj.input_history = new historyObj();
    }
    var history = obj.input_history;
    var lhist = history.store.length;
    var hpos = history.hpos + step;

    if (typeof(obj.input_history.current) === "undefined") {
        obj.input_history.current = lastentry;
    }
    if (hpos < 0) {
        // get the current but remove the cached one so it
        // can be replaced.
        obj.input_history.hpos = -1;
        var current = obj.input_history.current;
        obj.input_history.current = undefined;
        return current;
    }
    hpos = Math.max(0, Math.min(hpos, lhist-1));
    //console.log("lhist: " + lhist + " hpos: " + hpos + " current: " + obj.input_history.current);
    obj.input_history.hpos = hpos;
    return history.store[hpos];
}

/*
 * Initialization
 */

initialize = function() {

    // register events

    // single line input
    $(".input_singleline").on("submit", function(event) {
        // input from the single-line input field
        event.preventDefault(); // stop form from switching page
        var field = $(this).find("input");
        var msg = field.val();
        addHistory(this, msg);
        field.val("");
        dataSend("inputfield", msg);
        if (echo_to_textarea) {
            // echo to textfield
            toClass("textoutput", msg);
            toClass("lookoutput", msg);
            toClass("listoutput", msg);
        }
    });

    $(".input_singleline :input").on("keyup", function(event) {
        switch (event.keyCode) {
            case 13: // Enter
                event.preventDefault();
                $(this).trigger("submit");
                break
            case 38: // Up
                event.preventDefault();
                var lastentry = $(this).val();
                var hist = getHistory(this.form, lastentry, 1);
                if (hist) $(this).val(hist);
                break
            case 40: // Down
                event.preventDefault();
                var lastentry = $(this).val();
                var hist = getHistory(this.form, lastentry, -1);
                if (hist) $(this).val(hist);
                break
            default:
        }
    });

    // textarea input

    $(".input_multiline").on("submit", function(event) {
        // input from the textarea input
        event.preventDefault(); // stop form from switching page
        var field = $(this).find("textarea");
        var msg = field.val();
        addHistory(this, msg);
        field.val("");
        dataSend("inputfield", msg);
        if (echo_to_textarea) {
            // echo to textfield
            toClass("textarea", msg);
            toClass("lookarea", msg);
            toClass("listarea", msg);
        }
    });

    $(".input_multiline :input").on("keyup", function(event) {
        // Ctrl + <key> commands
        if (event.ctrlKey) {
            switch (event.keyCode) {
                case 13: // Ctrl + Enter
                    event.preventDefault();
                    $(this).trigger("submit");
                    break
                case 38: // Ctrl + Up
                    event.preventDefault();
                    var lastentry = $(this).val();
                    var hist = getHistory(this.form, lastentry, 1);
                    if (hist) $(this).val(hist);
                    break
                case 40: // Ctrl + Down
                    event.preventDefault();
                    var lastentry = $(this).val();
                    var hist = getHistory(this.form, lastentry, -1);
                    if (hist) $(this).val(hist);
                    break
                default:
            }
        }
    });

    // make sure textarea fills surrounding div
    //$('textarea').css({height:(300-$('form').height())+'px'});
    //$('textarea').css({'height':"100%"});

    // configurations
    $(".echo").on("change", function(event) {
        // configure echo on/off checkbox button
        event.preventDefault();
        echo_to_textarea = $(this).prop("checked");
    });

    // initialize the websocket connection
    //websocket = new WebSocket(wsurl);
    //websocket.onopen = function(event) {};
    //websocket.onclose = function(event) {};
    //websocket.onerror = function(event) {};
    //websocket.onmessage = dataOut;

}

/*
 * Kick system into gear first when
 * the document has loaded fully.
 */

$(document).ready(function() {
    // a small timeout to stop 'loading' indicator in Chrome
    setTimeout(function () {
        initialize();
    }, 500);
    // set an idle timer to avoid proxy servers to time out on us (every 3 minutes)
    setInterval(function() {
        dataSend("textinput", "idle");
    }, 60000*3);
});

<|endoftext|>


<commit_before>/*
 * Copyright 2015 Trim-marks Inc.
 *
 * This file is part of Vivliostyle UI.
 *
 * Vivliostyle UI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Vivliostyle UI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Vivliostyle UI.  If not, see <http://www.gnu.org/licenses/>.
 */

import ko from "knockout";
import urlParameters from "../stores/url-parameters";
import PageViewMode from "./page-view-mode";
import ZoomOptions from "./zoom-options";

function getViewerOptionsFromURL() {
    const renderAllPages = urlParameters.getParameter("renderAllPages")[0];
    const isEpub = urlParameters.getParameter("b").length && !urlParameters.getParameter("x").length;
    return {
        renderAllPages: (renderAllPages === "true" ? true : renderAllPages === "false" ? false : !isEpub),
        profile: (urlParameters.getParameter("profile")[0] === "true"),
        pageViewMode: PageViewMode.fromSpreadViewString(urlParameters.getParameter("spread")[0])
    };
}

function getDefaultValues() {
    return {
        fontSize: 16,
        profile: false,
        pageViewMode: PageViewMode.defaultMode(),
        zoom: ZoomOptions.createDefaultOptions()
    };
}

class ViewerOptions {
    constructor(options) {
        this.renderAllPages = ko.observable();
        this.fontSize = ko.observable();
        this.profile = ko.observable();
        this.pageViewMode = ko.observable();
        this.zoom = ko.observable();
        if (options) {
            this.copyFrom(options);
        } else {
            const defaultValues = getDefaultValues();
            const urlOptions = getViewerOptionsFromURL();
            this.renderAllPages(urlOptions.renderAllPages);
            this.fontSize(defaultValues.fontSize);
            this.profile(urlOptions.profile || defaultValues.profile);
            this.pageViewMode(urlOptions.pageViewMode || defaultValues.pageViewMode);
            this.zoom(defaultValues.zoom);

            // write spread parameter back to URL when updated
            this.pageViewMode.subscribe(pageViewMode => {
                urlParameters.setParameter("spread", pageViewMode.toSpreadViewString());
            });
        }
    }

    copyFrom(other) {
        this.renderAllPages(other.renderAllPages());
        this.fontSize(other.fontSize());
        this.profile(other.profile());
        this.pageViewMode(other.pageViewMode());
        this.zoom(other.zoom());
    }

    toObject() {
        return {
            renderAllPages: this.renderAllPages(),
            fontSize: this.fontSize(),
            pageViewMode: this.pageViewMode().toString(),
            zoom: this.zoom().zoom,
            fitToScreen: this.zoom().fitToScreen
        }
    }
}

ViewerOptions.getDefaultValues = getDefaultValues;

export default ViewerOptions;
<commit_msg>Default to renderAllPages=true for all document type<commit_after>/*
 * Copyright 2015 Trim-marks Inc.
 *
 * This file is part of Vivliostyle UI.
 *
 * Vivliostyle UI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Vivliostyle UI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Vivliostyle UI.  If not, see <http://www.gnu.org/licenses/>.
 */

import ko from "knockout";
import urlParameters from "../stores/url-parameters";
import PageViewMode from "./page-view-mode";
import ZoomOptions from "./zoom-options";

function getViewerOptionsFromURL() {
    const renderAllPages = urlParameters.getParameter("renderAllPages")[0];
    const isEpub = urlParameters.getParameter("b").length && !urlParameters.getParameter("x").length;
    return {
        // renderAllPages: (renderAllPages === "true" ? true : renderAllPages === "false" ? false : !isEpub),
        renderAllPages: (renderAllPages === "true" ? true : renderAllPages === "false" ? false : true),
        profile: (urlParameters.getParameter("profile")[0] === "true"),
        pageViewMode: PageViewMode.fromSpreadViewString(urlParameters.getParameter("spread")[0])
    };
}

function getDefaultValues() {
    return {
        fontSize: 16,
        profile: false,
        pageViewMode: PageViewMode.defaultMode(),
        zoom: ZoomOptions.createDefaultOptions()
    };
}

class ViewerOptions {
    constructor(options) {
        this.renderAllPages = ko.observable();
        this.fontSize = ko.observable();
        this.profile = ko.observable();
        this.pageViewMode = ko.observable();
        this.zoom = ko.observable();
        if (options) {
            this.copyFrom(options);
        } else {
            const defaultValues = getDefaultValues();
            const urlOptions = getViewerOptionsFromURL();
            this.renderAllPages(urlOptions.renderAllPages);
            this.fontSize(defaultValues.fontSize);
            this.profile(urlOptions.profile || defaultValues.profile);
            this.pageViewMode(urlOptions.pageViewMode || defaultValues.pageViewMode);
            this.zoom(defaultValues.zoom);

            // write spread parameter back to URL when updated
            this.pageViewMode.subscribe(pageViewMode => {
                urlParameters.setParameter("spread", pageViewMode.toSpreadViewString());
            });
        }
    }

    copyFrom(other) {
        this.renderAllPages(other.renderAllPages());
        this.fontSize(other.fontSize());
        this.profile(other.profile());
        this.pageViewMode(other.pageViewMode());
        this.zoom(other.zoom());
    }

    toObject() {
        return {
            renderAllPages: this.renderAllPages(),
            fontSize: this.fontSize(),
            pageViewMode: this.pageViewMode().toString(),
            zoom: this.zoom().zoom,
            fitToScreen: this.zoom().fitToScreen
        }
    }
}

ViewerOptions.getDefaultValues = getDefaultValues;

export default ViewerOptions;
<|endoftext|>


<commit_before>/*eslint-env node*/
const fs = require('fs');
const gulp = require('gulp');
const util = require('gulp-util');
const eslint = require('gulp-eslint');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const bump = require('gulp-bump');
const inquirer = require('inquirer');
const source = require('vinyl-source-stream');
const rollup = require('rollup-stream');
const buble = require('rollup-plugin-buble');
const del = require('del');
const sequence = require('run-sequence');
const semver = require('semver');
const es = require('event-stream');
const shell = require('shelljs');

const pkg = JSON.parse(fs.readFileSync('package.json'));
const paths = {
  src: 'src',
  dist: 'dist',
  main: pkg['main'],
  esmain: pkg['jsnext:main']
};

function bundle(format) {
  const banner = `/*! ${pkg.name} v${pkg.version} | ${pkg.license} License | ${pkg.homepage} */\n`;
  const moduleName = 'ngXhrPromisify';

  return rollup({
    entry: `${paths.src}/index.js`,
    plugins: [ buble() ],
    external: [ 'angular' ],
    globals: { 'angular': 'angular' },
    moduleName: moduleName,
    banner: banner,
    sourceMap: false,
    format: format || 'umd'
  });
}

gulp.task('bundle:es', () => {
  return bundle('es')
    .pipe(source(paths.esmain))
    .pipe(gulp.dest('.'));
});

gulp.task('bundle:umd', () => {
  return bundle('umd')
    .pipe(source(paths.main))
    .pipe(gulp.dest('.'));
});

gulp.task('minify:umd', () => {
  gulp.src(paths.main)
    .pipe(sourcemaps.init())
    .pipe(uglify({ preserveComments: 'license' }))
    .pipe(rename({ suffix: '.min' }))
    .pipe(sourcemaps.write('.', {
      includeContent: false,
      mapFile: name => name.replace(/\.js\.map$/, '.map')
    }))
    .pipe(gulp.dest(paths.dist));
});

gulp.task('lint', () => {
  return gulp.src(`${paths.src}/**/*.js`)
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

gulp.task('clean', () => {
  return del(paths.dist);
});

gulp.task('build', (callback) => {
  sequence('lint', 'clean', ['bundle:es', 'bundle:umd'], 'minify:umd', callback);
});

gulp.task('release:check', (callback) => {
  const branch = shell.exec('git rev-parse --abbrev-ref HEAD', { silent: true }).stdout.trim();
  if (branch !== 'master') {
    const red = util.colors.red;
    console.log(red('Switch to'), red.bold('master'), red('branch before continuing.'));
    process.exit(1);
  }

  const changes = shell.exec('git status --untracked-files=no --porcelain', { silent: true }).stdout.trim();
  if (changes) {
    console.log(util.colors.red('You have unstaged or uncommitted changes. Commit or stash before continuing.'));
    process.exit(1);
  }

  callback();
});

function bumpPackage(version) {
  return gulp.src('package.json')
    .pipe(bump({ version: version }))
    .pipe(gulp.dest('.'))
    .on('end', () => pkg.version = version);
}

function bumpChangeLog(version, previous) {
  const date = new Date().toISOString().slice(0, 10);
  const repo = pkg.repository.url.replace(/\.git$/, '');
  const entry = `## [${version}] \\(${date}\\)\n- TODO`;
  const link = `[${version}]: ${repo}/compare/v${previous}...v${version}`;

  return gulp.src('CHANGELOG.md')
    .pipe(es.map((file, callback) => {
      const changelog = file.contents.toString()
        .replace('# Change Log', `$&\n\n${entry}`)
        .concat(`${link}\n`);

      file.contents = new Buffer(changelog);
      callback(null, file);
    }))
    .pipe(gulp.dest('.'));
}

gulp.task('release:bump', () => {
  const choices = ['patch', 'minor', 'major'].map(type => {
    const version = semver.inc(pkg.version, type);
    return { name: `${type} (${version})`, value: version, short: type };
  });

  return inquirer.prompt({
    type: 'list',
    name: 'bump',
    message: 'Release type',
    choices: choices
  }).then(choice => {
    return new Promise((resolve, reject) => {
      es.merge(
        bumpPackage(choice.bump),
        bumpChangeLog(choice.bump, pkg.version)
      ).on('end', resolve);
    });
  });
});

gulp.task('release:changelog', () => {
  return inquirer.prompt({
    type: 'list',
    name: 'changelog',
    message: 'Edit CHANGELOG.md before continuing',
    choices: [{ name: `Release ${pkg.version}`, value: null, short: ' ' }]
  });
});

gulp.task('release:commit', (callback) => {
  const commands = [
    'git add -f package.json CHANGELOG.md',
    `git commit -m '${pkg.version}'`,
    'git checkout --detach',
    `git add -f ${paths.dist}`,
    `git commit -m '${pkg.version}'`,
    `git tag -f v${pkg.version}`,
    'git checkout master'
  ];

  commands.forEach(cmd => {
    const result = shell.exec(cmd, { silent: true });
    if (result.code !== 0) {
      console.log(util.colors.red(result.stderr.trim()));
      process.exit(1);
    }
  });

  callback();
});

gulp.task('release:publish', (callback) => {
  const commands = [
    `git push origin master v${pkg.version}`,
    `git checkout v${pkg.version}`,
    'npm publish',
    `git checkout master`
  ];

  inquirer.prompt({
    type: 'confirm',
    name: 'publish',
    message: `Publish ${pkg.version}`,
    default: false
  }).then(choice => {
    if(choice.publish) {
      commands.forEach(cmd => {
        const result = shell.exec(cmd, { silent: true });
        if (result.code !== 0) {
          console.log(util.colors.red(result.stderr.trim()));
          process.exit(1);
        }
      });
    }
    callback();
  });
});

gulp.task('release', (callback) => {
  sequence(
    'release:check',
    'release:bump',
    'build',
    'release:changelog',
    'release:commit',
    'release:publish',
    callback
  );
});

gulp.task('default', ['build']);
<commit_msg>Update gulp rollup configuration<commit_after>/*eslint-env node*/
const fs = require('fs');
const gulp = require('gulp');
const util = require('gulp-util');
const eslint = require('gulp-eslint');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');
const uglify = require('gulp-uglify');
const bump = require('gulp-bump');
const inquirer = require('inquirer');
const source = require('vinyl-source-stream');
const rollup = require('rollup-stream');
const buble = require('rollup-plugin-buble');
const del = require('del');
const sequence = require('run-sequence');
const semver = require('semver');
const es = require('event-stream');
const shell = require('shelljs');

const pkg = JSON.parse(fs.readFileSync('package.json'));
const paths = {
  src: 'src',
  dist: 'dist',
  main: pkg['main'],
  esmain: pkg['jsnext:main']
};

function bundle(format) {
  const banner = `/*! ${pkg.name} v${pkg.version} | ${pkg.license} License | ${pkg.homepage} */\n`;
  const moduleName = 'ngXhrPromisify';

  return rollup({
    input: `${paths.src}/index.js`,
    plugins: [ buble() ],
    external: [ 'angular' ],
    globals: { 'angular': 'angular' },
    name: moduleName,
    banner: banner,
    sourcemap: false,
    format: format || 'umd'
  });
}

gulp.task('bundle:es', () => {
  return bundle('es')
    .pipe(source(paths.esmain))
    .pipe(gulp.dest('.'));
});

gulp.task('bundle:umd', () => {
  return bundle('umd')
    .pipe(source(paths.main))
    .pipe(gulp.dest('.'));
});

gulp.task('minify:umd', () => {
  gulp.src(paths.main)
    .pipe(sourcemaps.init())
    .pipe(uglify({ preserveComments: 'license' }))
    .pipe(rename({ suffix: '.min' }))
    .pipe(sourcemaps.write('.', {
      includeContent: false,
      mapFile: name => name.replace(/\.js\.map$/, '.map')
    }))
    .pipe(gulp.dest(paths.dist));
});

gulp.task('lint', () => {
  return gulp.src(`${paths.src}/**/*.js`)
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

gulp.task('clean', () => {
  return del(paths.dist);
});

gulp.task('build', (callback) => {
  sequence('lint', 'clean', ['bundle:es', 'bundle:umd'], 'minify:umd', callback);
});

gulp.task('release:check', (callback) => {
  const branch = shell.exec('git rev-parse --abbrev-ref HEAD', { silent: true }).stdout.trim();
  if (branch !== 'master') {
    const red = util.colors.red;
    console.log(red('Switch to'), red.bold('master'), red('branch before continuing.'));
    process.exit(1);
  }

  const changes = shell.exec('git status --untracked-files=no --porcelain', { silent: true }).stdout.trim();
  if (changes) {
    console.log(util.colors.red('You have unstaged or uncommitted changes. Commit or stash before continuing.'));
    process.exit(1);
  }

  callback();
});

function bumpPackage(version) {
  return gulp.src('package.json')
    .pipe(bump({ version: version }))
    .pipe(gulp.dest('.'))
    .on('end', () => pkg.version = version);
}

function bumpChangeLog(version, previous) {
  const date = new Date().toISOString().slice(0, 10);
  const repo = pkg.repository.url.replace(/\.git$/, '');
  const entry = `## [${version}] \\(${date}\\)\n- TODO`;
  const link = `[${version}]: ${repo}/compare/v${previous}...v${version}`;

  return gulp.src('CHANGELOG.md')
    .pipe(es.map((file, callback) => {
      const changelog = file.contents.toString()
        .replace('# Change Log', `$&\n\n${entry}`)
        .concat(`${link}\n`);

      file.contents = new Buffer(changelog);
      callback(null, file);
    }))
    .pipe(gulp.dest('.'));
}

gulp.task('release:bump', () => {
  const choices = ['patch', 'minor', 'major'].map(type => {
    const version = semver.inc(pkg.version, type);
    return { name: `${type} (${version})`, value: version, short: type };
  });

  return inquirer.prompt({
    type: 'list',
    name: 'bump',
    message: 'Release type',
    choices: choices
  }).then(choice => {
    return new Promise((resolve, reject) => {
      es.merge(
        bumpPackage(choice.bump),
        bumpChangeLog(choice.bump, pkg.version)
      ).on('end', resolve);
    });
  });
});

gulp.task('release:changelog', () => {
  return inquirer.prompt({
    type: 'list',
    name: 'changelog',
    message: 'Edit CHANGELOG.md before continuing',
    choices: [{ name: `Release ${pkg.version}`, value: null, short: ' ' }]
  });
});

gulp.task('release:commit', (callback) => {
  const commands = [
    'git add -f package.json CHANGELOG.md',
    `git commit -m '${pkg.version}'`,
    'git checkout --detach',
    `git add -f ${paths.dist}`,
    `git commit -m '${pkg.version}'`,
    `git tag -f v${pkg.version}`,
    'git checkout master'
  ];

  commands.forEach(cmd => {
    const result = shell.exec(cmd, { silent: true });
    if (result.code !== 0) {
      console.log(util.colors.red(result.stderr.trim()));
      process.exit(1);
    }
  });

  callback();
});

gulp.task('release:publish', (callback) => {
  const commands = [
    `git push origin master v${pkg.version}`,
    `git checkout v${pkg.version}`,
    'npm publish',
    `git checkout master`
  ];

  inquirer.prompt({
    type: 'confirm',
    name: 'publish',
    message: `Publish ${pkg.version}`,
    default: false
  }).then(choice => {
    if(choice.publish) {
      commands.forEach(cmd => {
        const result = shell.exec(cmd, { silent: true });
        if (result.code !== 0) {
          console.log(util.colors.red(result.stderr.trim()));
          process.exit(1);
        }
      });
    }
    callback();
  });
});

gulp.task('release', (callback) => {
  sequence(
    'release:check',
    'release:bump',
    'build',
    'release:changelog',
    'release:commit',
    'release:publish',
    callback
  );
});

gulp.task('default', ['build']);
<|endoftext|>


<commit_before>/**
 * @module Core
 */
define([
    'core/modules/GelatoView',
    'core/modules/GelatoDialog',
    'core/modules/GelatoSidebar'
], function(GelatoView, GelatoDialog, GelatoSidebar) {

    /**
     * @class GelatoPage
     * @extends GelatoView
     */
    var GelatoPage = GelatoView.extend({
        /**
         * @property el
         * @type String
         */
        el: '#gelato-application',
        /**
         * @property title
         * @type String
         */
        title: app.strings.global.title,
        /**
         * @method disableForm
         * @param {String} [selector]
         * @returns {GelatoPage}
         */
        disableForm: function(selector) {
            this.$((selector ? selector + ' ': '') + ':input').prop('disabled', true);
            return this;
        },
        /**
         * @method enableForm
         * @param {String} [selector]
         * @returns {GelatoPage}
         */
        enableForm: function(selector) {
            this.$((selector ? selector: ' ') + ':input').prop('disabled', false);
            return this;
        },
        /**
         * @method renderDialog
         * @returns {GelatoPage}
         */
        renderDialog: function() {
            this.dialog = new GelatoDialog({el: this.$el, page: this});
            return this;
        },
        /**
         * @method renderSidebar
         * @returns {GelatoPage}
         */
        renderSidebar: function() {
            this.sidebar = new GelatoSidebar({el: this.$el, page: this});
            return this;
        },
        /**
         * @method renderTemplate
         * @param {String} template
         * @returns {GelatoPage}
         */
        renderTemplate: function(template) {
            GelatoView.prototype.renderTemplate.call(this, template);
            return this;
        },
        /**
         * @method getName
         * @returns {String}
         */
        getName: function() {
            return this.$('.gelato-page').attr('class').split(/\s/g)[1];
        },
        /**
         * @method remove
         * @returns {GelatoView}
         */
        remove: function() {
            if (this.dialog) {
                this.dialog.remove();
            }
            if (this.sidebar) {
                this.sidebar.remove();
            }
            return GelatoView.prototype.remove.call(this);
        }
    });

    return GelatoPage;

});<commit_msg>Removed unused dialog and sidebar methods from gelato page.<commit_after>/**
 * @module Core
 */
define([
    'core/modules/GelatoView',
    'core/modules/GelatoDialog',
    'core/modules/GelatoSidebar'
], function(GelatoView, GelatoDialog, GelatoSidebar) {

    /**
     * @class GelatoPage
     * @extends GelatoView
     */
    var GelatoPage = GelatoView.extend({
        /**
         * @property el
         * @type String
         */
        el: '#gelato-application',
        /**
         * @property title
         * @type String
         */
        title: app.strings.global.title,
        /**
         * @method disableForm
         * @param {String} [selector]
         * @returns {GelatoPage}
         */
        disableForm: function(selector) {
            this.$((selector ? selector + ' ' : '') + ':input').prop('disabled', true);
            return this;
        },
        /**
         * @method enableForm
         * @param {String} [selector]
         * @returns {GelatoPage}
         */
        enableForm: function(selector) {
            this.$((selector ? selector : ' ') + ':input').prop('disabled', false);
            return this;
        },
        /**
         * @method renderTemplate
         * @param {String} template
         * @returns {GelatoPage}
         */
        renderTemplate: function(template) {
            GelatoView.prototype.renderTemplate.call(this, template);
            return this;
        },
        /**
         * @method getName
         * @returns {String}
         */
        getName: function() {
            return this.$('.gelato-page').attr('class').split(/\s/g)[1];
        }
    });

    return GelatoPage;

});<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');

var DEFAULT_EXTEND_FIELD = 'extend',
    DEFAULT_EXCLUDE_FIELDS = [DEFAULT_EXTEND_FIELD, 'filename'];

/**
 * Default config transform which just returns original `options`
 * @param {Config} config
 * @private
 * @returns {Config}
 */
function defaultTransform(config) {
    return config;
}

/**
 * @class
 * @alias ConfigVisitor
 * @constructor
 * @param {ConfigLoader} loader
 * @param {ConfigPathResolver} pathResolver
 * @param {String} [extendField='extend']
 * @param {String[]} [excludeFields=['extend','filename']]
 */
function ConfigVisitor(loader, pathResolver, extendField, excludeFields) {
    if (!_.isString(extendField)) {
        extendField = DEFAULT_EXTEND_FIELD;
    }

    if (!_.isArray(excludeFields)) {
        excludeFields = [];
    }

    this.loader = loader;
    this.pathResolver = pathResolver;
    this.extendField = extendField;
    this.excludeFields = _.union(DEFAULT_EXCLUDE_FIELDS, excludeFields);
}

/**
 * Converts to `includes` options
 * @private
 * @param {String|String[]|Object<String,Function>|Object<String,Boolean>} obj
 * @returns {Object<String,Function>}
 */
ConfigVisitor.prototype.toIncludes = function(obj) {
    var arr = [];

    if (_.isArray(obj)) { // NOTE (@mdreizin): ['./webpack.config.js']
        arr = _.map(obj, function (filename) {
            return {
                filename: filename
            };
        });
    } else if (_.isString(obj)) { // NOTE (@mdreizin): './webpack.config.js'
        arr = [{
            filename: obj
        }];
    } else if (_.isObject(obj)) { // NOTE (@mdreizin): {'./webpack.config.js':Function|Boolean}
        arr = _.keys(obj).map(function (filename) {
            return {
                filename: filename,
                transform: obj[filename]
            };
        });
    }

    return _.reduce(arr, function (acc, x) {
        var key = this.pathResolver.resolve(x.filename);

        if (_.isBoolean(x.transform)) { // NOTE (@mdreizin): {'./webpack.config.js':Boolean}
            if (x.transform === true) {
                acc[key] = defaultTransform;
            }
        } else { // NOTE (@mdreizin): {'./webpack.config.js':Function}
            acc[key] = x.transform || defaultTransform;
        }

        return acc;
    }.bind(this), {});
};

/**
 * Walks recursively through `this.extendField` property and builds `visited` configs
 * @private
 * @param {Object} obj
 * @param {Object<String,Object>} visited
 */
ConfigVisitor.prototype.walk = function(obj, visited) {
    var field = obj && obj[this.extendField];

    if (!_.isUndefined(field)) {
        var includesOptions = this.toIncludes(field);

        _.keys(includesOptions).filter(function (filename, index, arr) {
            return arr.indexOf(filename) === index; // NOTE (@mdreizin): Skip `duplicates`
        }).filter(function (filename) {
            return _.isUndefined(visited[filename]); // NOTE (@mdreizin): Skip `visited` configs
        }).forEach(function (filename) {
            var currentConfig = this.loader.load(filename),
                currentOptions = includesOptions[filename];

            if (_.isFunction(currentOptions)) {
                currentConfig = currentOptions(currentConfig);
            }

            if (!_.isObject(currentConfig)) {
                currentConfig = {};
            }

            visited[filename] = currentConfig;

            this.walk(currentConfig, visited);
        }, this);
    }
};

/**
 * Returns `visited` configs
 * @param {Object} obj
 * @returns {Object<String,Config>}
 */
ConfigVisitor.prototype.visit = function(obj) {
    if (_.isUndefined(obj)) {
        throw new Error('obj is required');
    }

    var visited = {};

    this.walk(obj, visited);

    return visited;
};

/**
 * @module webpack-config/lib/configVisitor
 * @returns {ConfigVisitor}
 */
module.exports = ConfigVisitor;
<commit_msg>refactor(configVisitor): uses `lodash.includes()` instead of `Array.indexOf()`<commit_after>'use strict';

var _ = require('lodash');

var DEFAULT_EXTEND_FIELD = 'extend',
    DEFAULT_EXCLUDE_FIELDS = [DEFAULT_EXTEND_FIELD, 'filename'];

/**
 * Default config transform which just returns original `options`
 * @param {Config} config
 * @private
 * @returns {Config}
 */
function defaultTransform(config) {
    return config;
}

/**
 * @class
 * @alias ConfigVisitor
 * @constructor
 * @param {ConfigLoader} loader
 * @param {ConfigPathResolver} pathResolver
 * @param {String} [extendField='extend']
 * @param {String[]} [excludeFields=['extend','filename']]
 */
function ConfigVisitor(loader, pathResolver, extendField, excludeFields) {
    if (!_.isString(extendField)) {
        extendField = DEFAULT_EXTEND_FIELD;
    }

    if (!_.isArray(excludeFields)) {
        excludeFields = [];
    }

    this.loader = loader;
    this.pathResolver = pathResolver;
    this.extendField = extendField;
    this.excludeFields = _.union(DEFAULT_EXCLUDE_FIELDS, excludeFields);
}

/**
 * Converts to `includes` options
 * @private
 * @param {String|String[]|Object<String,Function>|Object<String,Boolean>} obj
 * @returns {Object<String,Function>}
 */
ConfigVisitor.prototype.toIncludes = function(obj) {
    var arr = [];

    if (_.isArray(obj)) { // NOTE (@mdreizin): ['./webpack.config.js']
        arr = _.map(obj, function (filename) {
            return {
                filename: filename
            };
        });
    } else if (_.isString(obj)) { // NOTE (@mdreizin): './webpack.config.js'
        arr = [{
            filename: obj
        }];
    } else if (_.isObject(obj)) { // NOTE (@mdreizin): {'./webpack.config.js':Function|Boolean}
        arr = _.keys(obj).map(function (filename) {
            return {
                filename: filename,
                transform: obj[filename]
            };
        });
    }

    return _.reduce(arr, function (acc, x) {
        var key = this.pathResolver.resolve(x.filename);

        if (_.isBoolean(x.transform)) { // NOTE (@mdreizin): {'./webpack.config.js':Boolean}
            if (x.transform === true) {
                acc[key] = defaultTransform;
            }
        } else { // NOTE (@mdreizin): {'./webpack.config.js':Function}
            acc[key] = x.transform || defaultTransform;
        }

        return acc;
    }.bind(this), {});
};

/**
 * Walks recursively through `this.extendField` property and builds `visited` configs
 * @private
 * @param {Object} obj
 * @param {Object<String,Object>} visited
 */
ConfigVisitor.prototype.walk = function(obj, visited) {
    var field = obj && obj[this.extendField];

    if (!_.isUndefined(field)) {
        var includesOptions = this.toIncludes(field);

        _.keys(includesOptions).filter(function (filename, index, arr) {
            return _.includes(arr, filename); // NOTE (@mdreizin): Skip `duplicates`
        }).filter(function (filename) {
            return _.isUndefined(visited[filename]); // NOTE (@mdreizin): Skip `visited` configs
        }).forEach(function (filename) {
            var currentConfig = this.loader.load(filename),
                currentOptions = includesOptions[filename];

            if (_.isFunction(currentOptions)) {
                currentConfig = currentOptions(currentConfig);
            }

            if (!_.isObject(currentConfig)) {
                currentConfig = {};
            }

            visited[filename] = currentConfig;

            this.walk(currentConfig, visited);
        }, this);
    }
};

/**
 * Returns `visited` configs
 * @param {Object} obj
 * @returns {Object<String,Config>}
 */
ConfigVisitor.prototype.visit = function(obj) {
    if (_.isUndefined(obj)) {
        throw new Error('obj is required');
    }

    var visited = {};

    this.walk(obj, visited);

    return visited;
};

/**
 * @module webpack-config/lib/configVisitor
 * @returns {ConfigVisitor}
 */
module.exports = ConfigVisitor;
<|endoftext|>