<commit_before>(function ($, Caman) {

var test_filters = [
  {filter: 'brightness', args: [50]},
  {filter: 'clip', args: [30]},
  {filter: 'channels', args: [{red: 20, green: -5, blue: -10}]},
  {filter: 'colorize', args: ['#AF3D15', 20]},
  {filter: 'contrast', args: [20]},
  {filter: 'gamma', args: [2.2]},
  {filter: 'greyscale', args: []},
  {filter: 'hue', args: [10]},
  {filter: 'invert', args: []},
  {filter: 'noise', args: [20]},
  {filter: 'saturation', args: [-50]},
  {filter: 'sepia', args: [50]}
];

Array.prototype.average = function () {
  var total = 0;
  for (var i = 0; i < this.length; i++) {
    if (typeof(this[i]) === 'number') {
      total += this[i];
    }
  }

  return (total / this.length);
};

if (!('console' in window)) {
  window.console = {
    log: function () {},
    info: function () {},
    error: function () {}
  };
}

var benchmark = (function () {
  var results = {},
  isSetup = false;

  var control = (function () {
    var current = 0,
    iterations = 1,
    current_iteration = 1,
    last_iteration = 1,
    current_test = null,
    finish_callback = null,
    plot = null;

    return {
      setUp: function () {
        // If canvas is already present, then remove it
        if ($('#test-canvas')) {
          $('#image-wrap').empty();
        }

        // Create new canvas for testing
        $('<canvas />')
          .attr('id', 'test-canvas')
          .appendTo('#image-wrap');

        if (!isSetup) {
          var row, cell, i, j;

          for (i = 0; i < iterations; i++) {
            $('<td />')
              .html('Iteration #' + (i+1))
              .appendTo('#test-header');
          }

          $('<td />').html('Average').appendTo('#test-header');

          for (i = 0; i < test_filters.length; i++) {
            row = $('<tr />');

            for (j = 0; j < iterations + 2; j++) {
              cell = $('<td />');

              if (j === 0) {
                cell.html(test_filters[i].filter);
              } else if (j === iterations + 1) {
                cell.attr('id', test_filters[i].filter + '_average');
              } else {
                cell.attr('id', test_filters[i].filter + '_' + j);
              }

              cell.appendTo(row);
            }

            $("#test-results").append(row);
          }

          isSetup = true;
        }
      },

      next: function () {
        current_test = test_filters[current];
        last_iteration = current_iteration;

        if (current_iteration == iterations) {
          current++;
          current_iteration = 1;
        } else {
          current_iteration++;
        }

        return current_test;
      },

      hasNext: function () {
        return test_filters[current] != undefined;
      },

      setIterations: function (num) {
        iterations = num;
      },

      registerFinished: function (callback) {
        finish_callback = callback;
      },

      fireFinished: function (results) {
        for (var filter in results) {
          if (results.hasOwnProperty(filter)) {
            results[filter].avg = results[filter].times.average();
          }
        }

        var chartData = [];
        var tickNames = [];
        var i = 1;
        $.each(results, function (filter, data) {
        	chartData.push({data: [[i, Math.round(data.avg)]], label: filter});
        	tickNames.push([i, filter]);
        	i++;
        });

        if (plot === null) {
        	plot = $.plot($("#test-graph"), chartData,
        	{
        		series: {
        			bars: {show: true, barWidth: 1.0, align: "center"}
        		},
        		xaxis: {
        			ticks: tickNames
        		},
        		legend: {show: false}
        	});
        }

        finish_callback(results);
      },

      iterationFinished: function (time) {
        $("#" + current_test.filter + "_" + last_iteration).html(time + "ms");

        if (current_iteration === 1) {
          this.filterFinished();
        }
      },

      filterFinished: function () {
        var filter = test_filters[current - 1].filter,
        avg = Math.round(results[filter].times.average());

        $('#' + filter + '_average').html(avg + 'ms');
      }
    };
  }());

  return {
    run: function (iterations, finish_callback) {
      var bench = this;

      if (finish_callback) {
        control.registerFinished(finish_callback);
      }

      if (iterations) {
        control.setIterations(iterations);
      }

      control.setUp();

      Caman('benchmark/testimg.jpg', "#test-canvas", function () {
        var test = control.next(),
        start, end;

        // Start timer
        start = new Date().getTime();

        this[test.filter].apply(this, test.args);

        this.finished(function () {
          var time;

          end = new Date().getTime();
          time = end - start;

          if (!results[test.filter]) {
            results[test.filter] = {
              times: []
            };
          }

          results[test.filter].times.push(time);

          console.log(test.filter + " finished in " + time + "ms");
          control.iterationFinished(time);

          if (control.hasNext()) {
            setTimeout(function () {
              bench.run();
            }, 100);
          } else {
            control.fireFinished(results);
          }
        });
      });
    }
  };
}());

window.benchmark = benchmark;

}(jQuery, Caman));<commit_msg>Updated benchmark page to work again<commit_after>(function ($, Caman) {

var test_filters = [
  {filter: 'brightness', args: [50]},
  {filter: 'clip', args: [30]},
  {filter: 'channels', args: [{red: 20, green: -5, blue: -10}]},
  {filter: 'colorize', args: ['#AF3D15', 20]},
  {filter: 'contrast', args: [20]},
  {filter: 'gamma', args: [2.2]},
  {filter: 'greyscale', args: []},
  {filter: 'hue', args: [10]},
  {filter: 'invert', args: []},
  {filter: 'noise', args: [20]},
  {filter: 'saturation', args: [-50]},
  {filter: 'sepia', args: [50]}
];

Array.prototype.average = function () {
  var total = 0;
  for (var i = 0; i < this.length; i++) {
    if (typeof(this[i]) === 'number') {
      total += this[i];
    }
  }

  return (total / this.length);
};

if (!('console' in window)) {
  window.console = {
    log: function () {},
    info: function () {},
    error: function () {}
  };
}

var benchmark = (function () {
  var results = {},
  isSetup = false;

  var control = (function () {
    var current = 0,
    iterations = 1,
    current_iteration = 1,
    last_iteration = 1,
    current_test = null,
    finish_callback = null,
    plot = null;

    return {
      setUp: function () {
        // If canvas is already present, then remove it
        if ($('#test-canvas')) {
          $('#image-wrap').empty();
        }

        // Create new canvas for testing
        $('<canvas />')
          .attr('id', 'test-canvas')
          .appendTo('#image-wrap');

        if (!isSetup) {
          var row, cell, i, j;

          for (i = 0; i < iterations; i++) {
            $('<td />')
              .html('Iteration #' + (i+1))
              .appendTo('#test-header');
          }

          $('<td />').html('Average').appendTo('#test-header');

          for (i = 0; i < test_filters.length; i++) {
            row = $('<tr />');

            for (j = 0; j < iterations + 2; j++) {
              cell = $('<td />');

              if (j === 0) {
                cell.html(test_filters[i].filter);
              } else if (j === iterations + 1) {
                cell.attr('id', test_filters[i].filter + '_average');
              } else {
                cell.attr('id', test_filters[i].filter + '_' + j);
              }

              cell.appendTo(row);
            }

            $("#test-results").append(row);
          }

          isSetup = true;
        }
      },

      next: function () {
        current_test = test_filters[current];
        last_iteration = current_iteration;

        if (current_iteration == iterations) {
          current++;
          current_iteration = 1;
        } else {
          current_iteration++;
        }

        return current_test;
      },

      hasNext: function () {
        return test_filters[current] != undefined;
      },

      setIterations: function (num) {
        iterations = num;
      },

      registerFinished: function (callback) {
        finish_callback = callback;
      },

      fireFinished: function (results) {
        for (var filter in results) {
          if (results.hasOwnProperty(filter)) {
            results[filter].avg = results[filter].times.average();
          }
        }

        var chartData = [];
        var tickNames = [];
        var i = 1;
        $.each(results, function (filter, data) {
        	chartData.push({data: [[i, Math.round(data.avg)]], label: filter});
        	tickNames.push([i, filter]);
        	i++;
        });

        if (plot === null) {
        	plot = $.plot($("#test-graph"), chartData,
        	{
        		series: {
        			bars: {show: true, barWidth: 1.0, align: "center"}
        		},
        		xaxis: {
        			ticks: tickNames
        		},
        		legend: {show: false}
        	});
        }

        finish_callback(results);
      },

      iterationFinished: function (time) {
        $("#" + current_test.filter + "_" + last_iteration).html(time + "ms");

        if (current_iteration === 1) {
          this.filterFinished();
        }
      },

      filterFinished: function () {
        var filter = test_filters[current - 1].filter,
        avg = Math.round(results[filter].times.average());

        $('#' + filter + '_average').html(avg + 'ms');
      }
    };
  }());

  return {
    run: function (iterations, finish_callback) {
      var bench = this;

      if (finish_callback) {
        control.registerFinished(finish_callback);
      }

      if (iterations) {
        control.setIterations(iterations);
      }

      control.setUp();

      Caman('benchmark/testimg.jpg', "#test-canvas", function () {
        var test = control.next(),
        start, end;

        // Start timer
        start = new Date().getTime();

        this[test.filter].apply(this, test.args);

        this.render(function () {
          var time;

          end = new Date().getTime();
          time = end - start;

          if (!results[test.filter]) {
            results[test.filter] = {
              times: []
            };
          }

          results[test.filter].times.push(time);

          console.log(test.filter + " finished in " + time + "ms");
          control.iterationFinished(time);

          if (control.hasNext()) {
            setTimeout(function () {
              bench.run();
            }, 100);
          } else {
            control.fireFinished(results);
          }
        });
      });
    }
  };
}());

window.benchmark = benchmark;

}(jQuery, Caman));<|endoftext|>


<commit_before>const Benchmark = require('benchmark')
const BigNumber = require('decimal.js')
const padRight = require('pad-right')
function pad (text) {
  return padRight(text, 40, ' ')
}

const results = []

function bigFactorial (n) {
  if (n.isZero()) {
    return new BigNumber(1) // 0! is per definition 1
  }

  let res = new BigNumber(n)
  let value = n.toNumber() - 1 // number
  while (value > 1) {
    res = res.times(value)
    value--
  }

  return new BigNumber(res)
}

function betterFactorial(n) {
  if(n % 2 === 1) {
    return n.times(betterFactorial(new BigNumber(n - 1)));
  }

  let p = n;
  let prod = n;
  let sum = n.toNumber();

  while(p > 2) {
    p -= 2;
    sum += p;
    prod = prod.times(sum);
  }

  return prod;
}

console.log('factorial 5 ' + bigFactorial(new BigNumber(6)))
console.log('new factorial 5 ' + betterFactorial(new BigNumber(6)))

const suite = new Benchmark.Suite()
suite
  .add(pad('bigFactorial for small numbers'), function () {
    const res = bigFactorial(new BigNumber(8))
    results.push(res)
  })
  .add(pad('new bigFactorial'), function () {
    const res = betterFactorial(new BigNumber(8));
    results.push(res)
  })
  .add(pad('bigFactorial for big numbers'), function () {
    const res = bigFactorial(new BigNumber(600))
    results.push(res)
  })
  .add(pad('new bigFactorial for big numbers'), function () {
    const res = betterFactorial(new BigNumber(600));
    results.push(res)
  })
  .on('cycle', function (event) {
    console.log(String(event.target))
  })
  .on('complete', function () {
  })
  .run()
<commit_msg>Fix linting issues (see PR #1690)<commit_after>const Benchmark = require('benchmark')
const BigNumber = require('decimal.js')
const padRight = require('pad-right')
function pad (text) {
  return padRight(text, 40, ' ')
}

const results = []

function bigFactorial (n) {
  if (n.isZero()) {
    return new BigNumber(1) // 0! is per definition 1
  }

  let res = new BigNumber(n)
  let value = n.toNumber() - 1 // number
  while (value > 1) {
    res = res.times(value)
    value--
  }

  return new BigNumber(res)
}

function betterFactorial (n) {
  if (n % 2 === 1) {
    return n.times(betterFactorial(new BigNumber(n - 1)))
  }

  let p = n
  let prod = n
  let sum = n.toNumber()

  while (p > 2) {
    p -= 2
    sum += p
    prod = prod.times(sum)
  }

  return prod
}

console.log('factorial 5 ' + bigFactorial(new BigNumber(6)))
console.log('new factorial 5 ' + betterFactorial(new BigNumber(6)))

const suite = new Benchmark.Suite()
suite
  .add(pad('bigFactorial for small numbers'), function () {
    const res = bigFactorial(new BigNumber(8))
    results.push(res)
  })
  .add(pad('new bigFactorial'), function () {
    const res = betterFactorial(new BigNumber(8))
    results.push(res)
  })
  .add(pad('bigFactorial for big numbers'), function () {
    const res = bigFactorial(new BigNumber(600))
    results.push(res)
  })
  .add(pad('new bigFactorial for big numbers'), function () {
    const res = betterFactorial(new BigNumber(600))
    results.push(res)
  })
  .on('cycle', function (event) {
    console.log(String(event.target))
  })
  .on('complete', function () {
  })
  .run()
<|endoftext|>


<commit_before>import assert from 'assert';
import BoxcarNotification from '../build.js';

let fail = () => {assert.ok(0);};

describe('constructor', () => {
    it('should get credential', (done) => {
        let credential = 'TEST';
        let bn = new BoxcarNotification(credential);
        assert.strictEqual(bn.userCredentials, credential);
        done();
    });
});

describe('static properties', () => {
    it('should have sounds property', (done) => {
        let validSounds = BoxcarNotification.VALID_SOUNDS;
        assert.ok(validSounds.length > 0);
        done();
    });

    it('should have api url property', (done) => {
        let apiUrl = BoxcarNotification.API_URL;
        assert.ok((/^https:\/\/.*boxcar.*$/).test(apiUrl));
        done();
    });
});

describe('send()', () => {
    let options;
    let bn;
    let notAuthorizedResponse = '{"Response":"Not Authorized"}';
    beforeEach((done) => {
        options = {
            title: 'title-title',
            longMessage: 'longMessage-longMessage',
            sound: 'beep-crisp',
            sourceName: 'sourceName-sourceName',
            iconUrl: 'iconUrl-iconUrl'
        };
        bn = new BoxcarNotification('TEST');
        done();
    });

    it('should done nomaly but api response "not authorized"', (done) => {
        bn.send(options).then((body) => {
            assert.deepEqual(body, notAuthorizedResponse);
        }).catch((e) => {
            fail();
        }).done(done);
    });

    it('should require title', (done) => {
        options.title = undefined;
        bn.send(options).then(() => {
            fail();
        }).catch((error) => {
            assert.ok(error);
        }).done(done);
    });

    it('should require longMessage', (done) => {
        options.longMessage = undefined;
        bn.send(options).then(() => {
            fail();
        }).catch((error) => {
            assert.ok(error);
        }).done(done);
    });

    it('should reject when sound option is invalid', (done) => {
        options.sound = 'testestestestes';
        bn.send(options).then(() => {
            fail();
        }).catch((error) => {
            assert.ok(error);
        }).done(done);
    });
});
<commit_msg>Set timeout time bit longer<commit_after>import assert from 'assert';
import BoxcarNotification from '../build.js';

let fail = () => {assert.ok(0);};

describe('constructor', () => {
    it('should get credential', (done) => {
        let credential = 'TEST';
        let bn = new BoxcarNotification(credential);
        assert.strictEqual(bn.userCredentials, credential);
        done();
    });
});

describe('static properties', () => {
    it('should have sounds property', (done) => {
        let validSounds = BoxcarNotification.VALID_SOUNDS;
        assert.ok(validSounds.length > 0);
        done();
    });

    it('should have api url property', (done) => {
        let apiUrl = BoxcarNotification.API_URL;
        assert.ok((/^https:\/\/.*boxcar.*$/).test(apiUrl));
        done();
    });
});

describe('send()', function () {
    this.timeout(10000);
    let options;
    let bn;
    let notAuthorizedResponse = '{"Response":"Not Authorized"}';
    beforeEach((done) => {
        options = {
            title: 'title-title',
            longMessage: 'longMessage-longMessage',
            sound: 'beep-crisp',
            sourceName: 'sourceName-sourceName',
            iconUrl: 'iconUrl-iconUrl'
        };
        bn = new BoxcarNotification('TEST');
        done();
    });

    it('should done nomaly but api response "not authorized"', (done) => {
        bn.send(options).then((body) => {
            assert.deepEqual(body, notAuthorizedResponse);
        }).catch((e) => {
            fail();
        }).done(done);
    });

    it('should require title', (done) => {
        options.title = undefined;
        bn.send(options).then(() => {
            fail();
        }).catch((error) => {
            assert.ok(error);
        }).done(done);
    });

    it('should require longMessage', (done) => {
        options.longMessage = undefined;
        bn.send(options).then(() => {
            fail();
        }).catch((error) => {
            assert.ok(error);
        }).done(done);
    });

    it('should reject when sound option is invalid', (done) => {
        options.sound = 'testestestestes';
        bn.send(options).then(() => {
            fail();
        }).catch((error) => {
            assert.ok(error);
        }).done(done);
    });
});
<|endoftext|>


<commit_before>'use strict';

var CircuitBreaker = require('../lib/index'),
    chai           = require('chai'),
    expect         = chai.expect,
    sinon          = require('sinon');

chai.should();

describe('Circuit Breaker', function(){
  var callback;

  beforeEach(function () {
    callback = sinon.stub();
  });

  describe('#constructor', function () {
    it('should be in closed state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.isClosed().should.be.true;
    });

    it('should zero out current number of failures', function () {
      var breaker = new CircuitBreaker(callback);
      breaker._numFailures.should.equal(0);
    });
  });

  describe('#forceOpen', function () {

    it('should enter open state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.isClosed().should.be.true;

      breaker.forceOpen();

      breaker.isOpen().should.be.true;
      breaker.isClosed().should.be.false;
    });

    it('should enter half-open state after reset timeout', function (done) {
      var breaker = new CircuitBreaker(callback, {resetTimeout: 10});
      breaker.forceOpen();

      breaker.isOpen().should.be.true;

      setTimeout(function () {
        breaker.isHalfOpen().should.be.true;

        return done();
      }, 11);
    });

    it('should remain in open state till reset timeout has been reached', function (done) {
      var breaker = new CircuitBreaker(callback, {resetTimeout: 20});
      breaker.forceOpen();

      breaker.isOpen().should.be.true;

      setTimeout(function () {
        breaker.isOpen().should.be.true;

        return done();
      }, 19);
    });

  });

  describe('#forceClosed', function () {

    it('should enter closed state', function () {
      var breaker = new CircuitBreaker(callback);

      breaker.forceOpen();
      breaker.isOpen().should.be.true;

      breaker.forceClosed();

      breaker.isClosed().should.be.true;
      breaker.isOpen().should.be.false;
    });

    it('should reset number of failrues to 0', function () {
      var breaker = new CircuitBreaker(callback);
      breaker._numFailures = 10;

      breaker.forceClosed();

      breaker._numFailures.should.equal(0);
    });

  });

  describe('#handleFailure', function () {

    it('should increment number of failures', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.handleFailure();

      breaker._numFailures.should.equal(1);
    });

    it('should open circuit after max failures is reached', function () {
      var breaker = new CircuitBreaker(callback, {maxFailures: 3});

      breaker.handleFailure();
      breaker.handleFailure();
      breaker.handleFailure();

      breaker.isClosed().should.be.false;
      breaker.isOpen().should.be.true;
    });

    it('should open circuit when in half-open state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.forceHalfOpen();

      breaker.handleFailure();

      breaker.isOpen().should.be.true;
      breaker.isClosed().should.be.false;
    });
  });

  describe('#handleSuccess', function () {

    it('should reset number of failures to 0', function () {
      var breaker = new CircuitBreaker(callback);
      breaker._numFailures = 10;

      breaker.handleSuccess();

      breaker._numFailures.should.equal(0);
    });

    it('should enter closed state when currently in half-open state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.forceHalfOpen();

      breaker.handleSuccess();

      breaker.isClosed().should.be.true;
    });

  });

  describe('invoke', function() {

    it('should remain closed on successful call', function(done){
      var breaker = new CircuitBreaker(callback);
      callback.withArgs('pass').yields(null, 'pass');

      breaker.invoke('pass').then(function (msg) {
        msg.should.equal('pass');
        breaker.isClosed().should.be.true;

        return done();
      }).fail(function(err) {
        return done(err);
      });
    });

    it('should enter open state after 3 failures', function(done){
      var breaker = new CircuitBreaker(callback, {maxFailures: 3});
      callback.yields(new Error('fail'));

      breaker.invoke('fail');
      breaker.invoke('fail');

      breaker.invoke('fail').then(null, function () {

        breaker.isOpen().should.be.true;

        return done();
      });

    });

    it('should fail fast when in open state', function(done){
      var breaker = new CircuitBreaker(callback);
      callback.yields(null, 'pass');
      breaker.forceOpen();

      breaker.invoke('pass').then(null, function (err) {

        breaker.isOpen().should.be.true;

        return done();
      });

    });
  });

});
<commit_msg>testing fail fast<commit_after>'use strict';

var CircuitBreaker = require('../lib/index'),
    chai           = require('chai'),
    expect         = chai.expect,
    sinon          = require('sinon');

chai.should();

describe('Circuit Breaker', function(){
  var callback;

  beforeEach(function () {
    callback = sinon.stub();
  });

  describe('#constructor', function () {
    it('should be in closed state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.isClosed().should.be.true;
    });

    it('should zero out current number of failures', function () {
      var breaker = new CircuitBreaker(callback);
      breaker._numFailures.should.equal(0);
    });
  });

  describe('#forceOpen', function () {

    it('should enter open state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.isClosed().should.be.true;

      breaker.forceOpen();

      breaker.isOpen().should.be.true;
      breaker.isClosed().should.be.false;
    });

    it('should enter half-open state after reset timeout', function (done) {
      var breaker = new CircuitBreaker(callback, {resetTimeout: 10});
      breaker.forceOpen();

      breaker.isOpen().should.be.true;

      setTimeout(function () {
        breaker.isHalfOpen().should.be.true;

        return done();
      }, 11);
    });

    it('should remain in open state till reset timeout has been reached', function (done) {
      var breaker = new CircuitBreaker(callback, {resetTimeout: 20});
      breaker.forceOpen();

      breaker.isOpen().should.be.true;

      setTimeout(function () {
        breaker.isOpen().should.be.true;

        return done();
      }, 19);
    });

  });

  describe('#forceClosed', function () {

    it('should enter closed state', function () {
      var breaker = new CircuitBreaker(callback);

      breaker.forceOpen();
      breaker.isOpen().should.be.true;

      breaker.forceClosed();

      breaker.isClosed().should.be.true;
      breaker.isOpen().should.be.false;
    });

    it('should reset number of failrues to 0', function () {
      var breaker = new CircuitBreaker(callback);
      breaker._numFailures = 10;

      breaker.forceClosed();

      breaker._numFailures.should.equal(0);
    });

  });

  describe('#handleFailure', function () {

    it('should increment number of failures', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.handleFailure();

      breaker._numFailures.should.equal(1);
    });

    it('should open circuit after max failures is reached', function () {
      var breaker = new CircuitBreaker(callback, {maxFailures: 3});

      breaker.handleFailure();
      breaker.handleFailure();
      breaker.handleFailure();

      breaker.isClosed().should.be.false;
      breaker.isOpen().should.be.true;
    });

    it('should open circuit when in half-open state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.forceHalfOpen();

      breaker.handleFailure();

      breaker.isOpen().should.be.true;
      breaker.isClosed().should.be.false;
    });
  });

  describe('#handleSuccess', function () {

    it('should reset number of failures to 0', function () {
      var breaker = new CircuitBreaker(callback);
      breaker._numFailures = 10;

      breaker.handleSuccess();

      breaker._numFailures.should.equal(0);
    });

    it('should enter closed state when currently in half-open state', function () {
      var breaker = new CircuitBreaker(callback);
      breaker.forceHalfOpen();

      breaker.handleSuccess();

      breaker.isClosed().should.be.true;
    });

  });

  describe('invoke', function() {

    it('should remain closed on successful call', function(done){
      var breaker = new CircuitBreaker(callback);
      callback.withArgs('pass').yields(null, 'pass');

      breaker.invoke('pass').then(function (msg) {
        msg.should.equal('pass');
        breaker.isClosed().should.be.true;

        return done();
      }).fail(function(err) {
        return done(err);
      });
    });

    it('should enter open state after 3 failures', function(done){
      var breaker = new CircuitBreaker(callback, {maxFailures: 3});
      callback.yields(new Error('fail'));

      breaker.invoke('fail');
      breaker.invoke('fail');

      breaker.invoke('fail').fail(function () {

        breaker.isOpen().should.be.true;

        return done();
      });

    });

    it('should fail fast when in open state', function(done){
      var breaker = new CircuitBreaker(callback);
      callback.yields(null, 'pass');
      breaker.forceOpen();

      breaker.invoke('pass').fail(function (err) {
        'Error: Circuit Breaker open'.should.equal(err.toString() );

        return done();
      });

    });
  });

});
<|endoftext|>


<commit_before>describe('services', function () {
    var $httpBackend, result;

    beforeEach(module('myApp'));
    beforeEach(inject(function($injector) {
        $httpBackend = $injector.get('$httpBackend');
        result = undefined;
    }));

    afterEach(function() {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    describe('UserService', function () {
        it('should be defined', inject(function (UserService) {
            expect(UserService).toBeDefined();
            expect(UserService.find).toBeDefined();
            expect(UserService.get).toBeDefined();
            expect(UserService.del).toBeDefined();
        }));

        it('should get all users directly from the rest api', inject(function (UserService) {
            $httpBackend.whenGET('/api/Users/').respond(200, 'apiResponse');

            UserService.find().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should get single users directly from the rest api', inject(function (UserService) {
            $httpBackend.whenGET('/api/Users/1').respond(200, 'apiResponse');

            UserService.get(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should delete user directly via the rest api', inject(function (UserService) {
            $httpBackend.whenDELETE('/api/Users/1').respond(200, 'apiResponse');

            UserService.del(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should create user directly via the rest api', inject(function (UserService) {
            $httpBackend.whenPOST('/api/Users/').respond(200, 'apiResponse');

            UserService.save().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

    });

    describe('ProductService', function () {
        it('should be defined', inject(function (ProductService) {
            expect(ProductService).toBeDefined();
            expect(ProductService.find).toBeDefined();
            expect(ProductService.get).toBeDefined();
            expect(ProductService.search).toBeDefined();
        }));

        it('should get all products directly from the rest api', inject(function (ProductService) {
            $httpBackend.whenGET('/api/Products/').respond(200, 'apiResponse');

            ProductService.find().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should get single product directly from the rest api', inject(function (ProductService) {
            $httpBackend.whenGET('/api/Products/1').respond(200, 'apiResponse');

            ProductService.get(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

    });

    describe('FeedbackService', function () {
        it('should be defined', inject(function (FeedbackService) {
            expect(FeedbackService).toBeDefined();
            expect(FeedbackService.find).toBeDefined();
            expect(FeedbackService.save).toBeDefined();
            expect(FeedbackService.del).toBeDefined();
        }));

        it('should get all feedback directly from the rest api', inject(function (FeedbackService) {
            $httpBackend.whenGET('/api/Feedbacks/').respond(200, 'apiResponse');

            FeedbackService.find().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should delete feedback directly via the rest api', inject(function (FeedbackService) {
            $httpBackend.whenDELETE('/api/Feedbacks/1').respond(200, 'apiResponse');

            FeedbackService.del(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should create feedback directly via the rest api', inject(function (FeedbackService) {
            $httpBackend.whenPOST('/api/Feedbacks/').respond(200, 'apiResponse');

            FeedbackService.save().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));
    });

});
<commit_msg>testing login service call<commit_after>describe('services', function () {
    var $httpBackend, result;

    beforeEach(module('myApp'));
    beforeEach(inject(function($injector) {
        $httpBackend = $injector.get('$httpBackend');
        result = undefined;
    }));

    afterEach(function() {
        $httpBackend.verifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    describe('UserService', function () {
        it('should be defined', inject(function (UserService) {
            expect(UserService).toBeDefined();
            expect(UserService.find).toBeDefined();
            expect(UserService.get).toBeDefined();
            expect(UserService.del).toBeDefined();
        }));

        it('should get all users directly from the rest api', inject(function (UserService) {
            $httpBackend.whenGET('/api/Users/').respond(200, 'apiResponse');

            UserService.find().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should get single users directly from the rest api', inject(function (UserService) {
            $httpBackend.whenGET('/api/Users/1').respond(200, 'apiResponse');

            UserService.get(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should delete user directly via the rest api', inject(function (UserService) {
            $httpBackend.whenDELETE('/api/Users/1').respond(200, 'apiResponse');

            UserService.del(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should create user directly via the rest api', inject(function (UserService) {
            $httpBackend.whenPOST('/api/Users/').respond(200, 'apiResponse');

            UserService.save().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should login user directly via the rest api', inject(function (UserService) {
            $httpBackend.whenPOST('/rest/user/login').respond(200, 'apiResponse');

            UserService.login().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

    });

    describe('ProductService', function () {
        it('should be defined', inject(function (ProductService) {
            expect(ProductService).toBeDefined();
            expect(ProductService.find).toBeDefined();
            expect(ProductService.get).toBeDefined();
            expect(ProductService.search).toBeDefined();
        }));

        it('should get all products directly from the rest api', inject(function (ProductService) {
            $httpBackend.whenGET('/api/Products/').respond(200, 'apiResponse');

            ProductService.find().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should get single product directly from the rest api', inject(function (ProductService) {
            $httpBackend.whenGET('/api/Products/1').respond(200, 'apiResponse');

            ProductService.get(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

    });

    describe('FeedbackService', function () {
        it('should be defined', inject(function (FeedbackService) {
            expect(FeedbackService).toBeDefined();
            expect(FeedbackService.find).toBeDefined();
            expect(FeedbackService.save).toBeDefined();
            expect(FeedbackService.del).toBeDefined();
        }));

        it('should get all feedback directly from the rest api', inject(function (FeedbackService) {
            $httpBackend.whenGET('/api/Feedbacks/').respond(200, 'apiResponse');

            FeedbackService.find().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should delete feedback directly via the rest api', inject(function (FeedbackService) {
            $httpBackend.whenDELETE('/api/Feedbacks/1').respond(200, 'apiResponse');

            FeedbackService.del(1).success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));

        it('should create feedback directly via the rest api', inject(function (FeedbackService) {
            $httpBackend.whenPOST('/api/Feedbacks/').respond(200, 'apiResponse');

            FeedbackService.save().success(function (data) { result = data; });
            $httpBackend.flush();

            expect(result).toBe('apiResponse');
        }));
    });

});
<|endoftext|>


<commit_before>/* eslint-env mocha */

import { Template } from '../index.js';
import { define } from '../src/lib/define.js';
import {
    TestComponent1,
    TestComponent2,
} from './components/dna-properties.js';
import { Wrapper } from './utils/wrapper.js';

const WRAPPER = new Wrapper();
define('test1-properties-component', TestComponent1);
define('test2-properties-component', TestComponent2);

describe('DNAPropertiesComponent', () => {
    describe('Unit: DNAPropertiesComponent > creation', () => {
        let template = new Template(' \
            <test1-properties-component \
                name="Alan" \
                last-name="Turing" \
                var="1234" \
                married> \
            </test1-properties-component> \
        ');
        template.render(WRAPPER);
        let elem = WRAPPER.querySelector('test1-properties-component');

        it('init element\'s properties', () => {
            assert.equal(elem.name, 'Alan');
            assert.equal(elem.lastName, 'Turing');
            assert.equal(elem.married, true);
            assert.equal(elem.var, 1234);
        });

        it('observe properties changes', () => {
            let changedSingle = false;
            let changedAll = false;
            elem.observeProperty('age', () => {
                changedSingle = true;
            });
            elem.observeProperties(() => {
                changedAll = true;
            });
            elem.age = 41;
            assert(changedSingle);
            assert(changedAll);
        });
    });

    describe('Unit: DNAPropertiesComponent > props 2 attrs', () => {
        let template = new Template(
            '<test2-properties-component></test2-properties-component>'
        );
        template.render(WRAPPER);
        let elem = WRAPPER.querySelector('test2-properties-component');

        it('check sync between property and attribute', () => {
            elem.title = 'DNA Test';
            assert.equal(elem.getAttribute('title'), 'DNA Test');
        });
        it('check sync between custom property and attribute', () => {
            elem.var = 1234;
            elem.id = 'dna-test';
            assert.equal(elem.getAttribute('var'), '1234');
            assert.equal(elem.getAttribute('id'), 'dna-test');
        });
        it('check sync between custom computed property and attribute', () => {
            elem.myVar = true;
            assert.equal(elem.getAttribute('my-var'), '');
            elem.myVar = false;
            assert.equal(elem.getAttribute('my-var'), null);
        });
        it('check sync between custom computed property with setter and attribute', () => {
            elem.myVar3 = true;
            assert.equal(elem.getAttribute('my-var3'), 'DNA Test');
        });
    });

    describe('Unit: DNAAttributesComponent > attrs 2 props', () => {
        let template = new Template('attrs', ' \
            <test2-properties-component \
            ${attrs ? ` \
                alt="DNA Test 2" \
                mine="1234" \
                my-var2="true" \
            ` : \'\'} \
            ></test2-properties-component> \
        ');
        template.render(WRAPPER);
        let elem = WRAPPER.querySelector('test2-properties-component');

        before((done) => {
            template.render(WRAPPER, true);
            done();
        });
        it('check sync between attribute and property', () => {
            assert.equal(elem.alt, 'DNA Test 2');
        });
        it('check sync between custom attribute and property', () => {
            assert.equal(elem.mine, 1234);
        });
        it('check sync between custom computed attribute and property', () => {
            assert.equal(elem.myVar2, true);
        });
    });
});
<commit_msg>test: add test for property change event<commit_after>/* eslint-env mocha */

import { Template } from '../index.js';
import { define } from '../src/lib/define.js';
import {
    TestComponent1,
    TestComponent2,
} from './components/dna-properties.js';
import { Wrapper } from './utils/wrapper.js';

const WRAPPER = new Wrapper();
define('test1-properties-component', TestComponent1);
define('test2-properties-component', TestComponent2);

describe('DNAPropertiesComponent', () => {
    describe('Unit: DNAPropertiesComponent > creation', () => {
        let template = new Template(' \
            <test1-properties-component \
                name="Alan" \
                last-name="Turing" \
                var="1234" \
                married> \
            </test1-properties-component> \
        ');
        template.render(WRAPPER);
        const elem = WRAPPER.querySelector('test1-properties-component');

        it('init element\'s properties', () => {
            assert.equal(elem.name, 'Alan');
            assert.equal(elem.lastName, 'Turing');
            assert.equal(elem.married, true);
            assert.equal(elem.var, 1234);
        });

        it('observe properties changes', () => {
            let changedSingle = false;
            let changedAll = false;
            elem.observeProperty('age', () => {
                changedSingle = true;
            });
            elem.observeProperties(() => {
                changedAll = true;
            });
            elem.age = 41;
            assert(changedSingle);
            assert(changedAll);
        });
    });

    describe('Unit: DNAPropertiesComponent > props 2 attrs', () => {
        let template = new Template(
            '<test2-properties-component></test2-properties-component>'
        );
        template.render(WRAPPER);
        const elem = WRAPPER.querySelector('test2-properties-component');

        it('check sync between property and attribute', () => {
            elem.title = 'DNA Test';
            assert.equal(elem.getAttribute('title'), 'DNA Test');
        });
        it('check sync between custom property and attribute', () => {
            elem.var = 1234;
            elem.id = 'dna-test';
            assert.equal(elem.getAttribute('var'), '1234');
            assert.equal(elem.getAttribute('id'), 'dna-test');
        });
        it('check sync between custom computed property and attribute', () => {
            elem.myVar = true;
            assert.equal(elem.getAttribute('my-var'), '');
            elem.myVar = false;
            assert.equal(elem.getAttribute('my-var'), null);
        });
        it('check sync between custom computed property with setter and attribute', () => {
            elem.myVar3 = true;
            assert.equal(elem.getAttribute('my-var3'), 'DNA Test');
        });
        it('dispatch event', () => {
            let triggered = 0;
            elem.addEventListener('changed', () => {
                triggered++;
            });
            elem.myVar3 = true;
            elem.myVar3 = false;
            assert.equal(triggered, 1);
        });
    });

    describe('Unit: DNAAttributesComponent > attrs 2 props', () => {
        let template = new Template('attrs', ' \
            <test2-properties-component \
            ${attrs ? ` \
                alt="DNA Test 2" \
                mine="1234" \
                my-var2="true" \
            ` : \'\'} \
            ></test2-properties-component> \
        ');
        template.render(WRAPPER);
        const elem = WRAPPER.querySelector('test2-properties-component');

        before((done) => {
            template.render(WRAPPER, true);
            done();
        });
        it('check sync between attribute and property', () => {
            assert.equal(elem.alt, 'DNA Test 2');
        });
        it('check sync between custom attribute and property', () => {
            assert.equal(elem.mine, 1234);
        });
        it('check sync between custom computed attribute and property', () => {
            assert.equal(elem.myVar2, true);
        });
    });
});
<|endoftext|>


<commit_before>/* eslint-env mocha */
/* eslint-disable no-unused-expressions */
'use strict'

const async = require('async')
const dotenv = require('dotenv')
const expect = require('chai').expect
const kill = require('tree-kill')
const path = require('path')
const rp = require('request-promise-native')
const tmp = require('tmp')

const exec = require('./../../lib/exec')

const payloadBuilder = require('./../util/github-webhook-payload-builder')
const retry = require('./../util/retry')
const wait = require('./../util/wait')
const webhookSimulator = require('./../util/github-webhook-simulator')

const PI_DAB_ROOT_DIR = path.resolve(__dirname, './../..')

const getPortFromCompose = () => exec('docker-compose exec -T main bash -c "echo \\$PORT"', {
  cwd: PI_DAB_ROOT_DIR
}).then(stdio => parseInt(stdio.stdout.trim(), 10))

const removeDockerComposeContainers = () => {
  console.log('test: removing compose containers...')
  return retry(5, () => exec('docker-compose down', {
    cwd: PI_DAB_ROOT_DIR
  }), 1000)
    .then(() => console.log('test: removed compose containers'))
    .catch(err => console.error(`test: failed to remove compose containers, continuing anyway: ${err}`))
}

const startPiDabUntilTunnelOpened = function ({ env }) {
  const exec = require('child_process').exec
  return new Promise((resolve, reject) => {
    const cp = exec('docker-compose up --build --force-recreate', {
      cwd: path.resolve(__dirname, './../..'),
      env: env
    })
    cp.stdout.on('data', function (data) {
      console.log(data)
      if (/generated secret/i.test(data.toString())) {
        const matches = /(.{8}-.{4}-.{4}-.{4}-.{12})/.exec(data.toString())
        if (matches) {
          cp.secret = matches[0]
        }
      }
      if (/opened/i.test(data.toString())) {
        console.log('test: compose started')
        resolve(cp)
      }
    })
    // cp.stderr.on('data', reject)
  })
}

const simulateStatusUpdateFromTravisForPiDabToHelloWorld = ({ secret, port }) => webhookSimulator({ port })
  .send(payloadBuilder()
    .contextTravisPush()
    .sha('70fa52b179dee6f6c555f1a3e4b912a8af28d7b8')
    .repo('mlenkeit/pi-dab')
    .build({ secret }))

const sendGetRequestToHelloEndpoint = port => rp.get({
  uri: `http://localhost:${port}/hello`,
  simple: false,
  resolveWithFullResponse: true
}).then(response => {
  console.log(`test: GET request to hello endpoint returned status code ${response.statusCode}`)
  return response
})

describe('Docker Compose Test', function () {
  beforeEach(function () {
    this.cps = []

    dotenv.config({ path: path.resolve(__dirname, './../../.env.test') })
    this.env = Object.assign({}, process.env)
    this.env.PROJECTS = path.resolve(__dirname, './../fixture/projects2.js')
    this.env.PROJECTS_ROOT_DIR = tmp.dirSync().name
  })

  beforeEach('remove compose containers before execution', function () {
    return removeDockerComposeContainers()
  })

  afterEach(function (done) {
    async.each(this.cps, function (cp, cb) {
      var pid = cp.pid
      kill(pid, 'SIGKILL', function (/* err */) {
        cb()
      })
    }, done)
  })

  afterEach('remove compose containers after execution', function () {
    return removeDockerComposeContainers()
  })

  it('auto-updates itself', function () {
    return startPiDabUntilTunnelOpened({ env: this.env })
      .then(cp => {
        this.cps.push(cp)
        return wait(5000)
          .then(() => getPortFromCompose())
          .then(port => {
            console.log(`test: found exposed port ${port}`)

            return sendGetRequestToHelloEndpoint(port)
              .then(response => expect(response.statusCode).to.equal(404))
              .then(() => simulateStatusUpdateFromTravisForPiDabToHelloWorld({ secret: cp.secret, port }))
              .then(() => wait(30000))
              .then(() => sendGetRequestToHelloEndpoint(port))
              .then(response => expect(response.statusCode).to.equal(200))
          })
      })
  })
})
<commit_msg>test(compose.spec): retry assertion multiple times<commit_after>/* eslint-env mocha */
/* eslint-disable no-unused-expressions */
'use strict'

const async = require('async')
const dotenv = require('dotenv')
const expect = require('chai').expect
const kill = require('tree-kill')
const path = require('path')
const rp = require('request-promise-native')
const tmp = require('tmp')

const exec = require('./../../lib/exec')

const payloadBuilder = require('./../util/github-webhook-payload-builder')
const retry = require('./../util/retry')
const wait = require('./../util/wait')
const webhookSimulator = require('./../util/github-webhook-simulator')

const PI_DAB_ROOT_DIR = path.resolve(__dirname, './../..')

const getPortFromCompose = () => exec('docker-compose exec -T main bash -c "echo \\$PORT"', {
  cwd: PI_DAB_ROOT_DIR
}).then(stdio => parseInt(stdio.stdout.trim(), 10))

const removeDockerComposeContainers = () => {
  console.log('test: removing compose containers...')
  return retry(5, () => exec('docker-compose down', {
    cwd: PI_DAB_ROOT_DIR
  }), 1000)
    .then(() => console.log('test: removed compose containers'))
    .catch(err => console.error(`test: failed to remove compose containers, continuing anyway: ${err}`))
}

const startPiDabUntilTunnelOpened = function ({ env }) {
  const exec = require('child_process').exec
  return new Promise((resolve, reject) => {
    const cp = exec('docker-compose up --build --force-recreate', {
      cwd: path.resolve(__dirname, './../..'),
      env: env
    })
    cp.stdout.on('data', function (data) {
      console.log(data)
      if (/generated secret/i.test(data.toString())) {
        const matches = /(.{8}-.{4}-.{4}-.{4}-.{12})/.exec(data.toString())
        if (matches) {
          cp.secret = matches[0]
        }
      }
      if (/opened/i.test(data.toString())) {
        console.log('test: compose started')
        resolve(cp)
      }
    })
    // cp.stderr.on('data', reject)
  })
}

const simulateStatusUpdateFromTravisForPiDabToHelloWorld = ({ secret, port }) => webhookSimulator({ port })
  .send(payloadBuilder()
    .contextTravisPush()
    .sha('70fa52b179dee6f6c555f1a3e4b912a8af28d7b8')
    .repo('mlenkeit/pi-dab')
    .build({ secret }))

const sendGetRequestToHelloEndpoint = port => rp.get({
  uri: `http://localhost:${port}/hello`,
  simple: false,
  resolveWithFullResponse: true
}).then(response => {
  console.log(`test: GET request to hello endpoint returned status code ${response.statusCode}`)
  return response
})

describe('Docker Compose Test', function () {
  beforeEach(function () {
    this.cps = []

    dotenv.config({ path: path.resolve(__dirname, './../../.env.test') })
    this.env = Object.assign({}, process.env)
    this.env.PROJECTS = path.resolve(__dirname, './../fixture/projects2.js')
    this.env.PROJECTS_ROOT_DIR = tmp.dirSync().name
  })

  beforeEach('remove compose containers before execution', function () {
    return removeDockerComposeContainers()
  })

  afterEach(function (done) {
    async.each(this.cps, function (cp, cb) {
      var pid = cp.pid
      kill(pid, 'SIGKILL', function (/* err */) {
        cb()
      })
    }, done)
  })

  afterEach('remove compose containers after execution', function () {
    return removeDockerComposeContainers()
  })

  it('auto-updates itself', function () {
    return startPiDabUntilTunnelOpened({ env: this.env })
      .then(cp => {
        this.cps.push(cp)
        return wait(5000)
          .then(() => getPortFromCompose())
          .then(port => {
            console.log(`test: found exposed port ${port}`)

            return sendGetRequestToHelloEndpoint(port)
              .then(response => expect(response.statusCode).to.equal(404))
              .then(() => simulateStatusUpdateFromTravisForPiDabToHelloWorld({ secret: cp.secret, port }))
              .then(() => wait(30000))
              .then(() => retry(5, () =>
                sendGetRequestToHelloEndpoint(port)
                  .then(response => expect(response.statusCode).to.equal(200)), 10000))
          })
      })
  })
})
<|endoftext|>


<commit_before>const { fork } = require('child_process');
const fs = require('fs');
const path = require('path');

const assert = require('chai').assert;
const chokidar = require('chokidar');
const cpr = require('cpr');
const request = require('superagent');
const rimraf = require('rimraf');
const tmp = require('tmp');
const yaml = require('js-yaml');

const { findOpenPortNumbers } = require('../common/server-helper');

const GATEWAY_STARTUP_WAIT_TIME = 5000;
const TEST_TIMEOUT = 10000;

/*
    1) Copy config to a temp directory.
    2) Execute a child process with `process.env.EG_CONFIG_DIR` set to the temp directory.
    3) Watch the temp directory config file from the test.
    4) Do a baseline request to make sure the original gateway config is working.
    5) Write a new gateway config
    6) When the test watcher fires, make another HTTP request to confirm the new config is working.
    7) Clean up the temp directory.
*/

const baseConfigDirectory = path.join(__dirname, '..', 'fixtures', 'hot-reload');

describe('hot-reload', () => {
  describe('gateway config', () => {
    let testGatewayConfigPath = null;
    let testGatewayConfigData = null;
    let childProcess = null;
    let originalGatewayPort = null;
    let watcher = null;

    before(function (done) {
      this.timeout(TEST_TIMEOUT);
      tmp.dir((err, tempPath) => {
        if (err) {
          return done(err);
        }

        cpr(baseConfigDirectory, tempPath, (err, files) => {
          if (err) {
            return done(err);
          }

          cpr(path.join(__dirname, '../../lib/config/models'), path.join(tempPath, 'models'), (err, files) => {
            if (err) {
              return done(err);
            }

            testGatewayConfigPath = path.join(tempPath, 'gateway.config.yml');

            findOpenPortNumbers(3).then(ports => {
              fs.readFile(testGatewayConfigPath, (err, configData) => {
                if (err) {
                  return done(err);
                }

                testGatewayConfigData = yaml.load(configData);

                testGatewayConfigData.http.port = ports[0];
                testGatewayConfigData.https.port = ports[1];
                testGatewayConfigData.admin.port = ports[2];
                testGatewayConfigData.serviceEndpoints.backend.url =
                  `http://localhost:${ports[2]}`;

                originalGatewayPort = ports[0];

                fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
                  if (err) {
                    return done(err);
                  }

                  const childEnv = Object.assign({}, process.env);
                  childEnv.EG_CONFIG_DIR = tempPath;

                  // Tests, by default have config watch disabled.
                  // Need to remove this paramter in the child process.
                  delete childEnv.EG_DISABLE_CONFIG_WATCH;

                  const modulePath = path.join(__dirname, '../..', 'lib', 'index.js');
                  childProcess = fork(modulePath, [], {
                    cwd: tempPath,
                    env: childEnv
                  });

                  childProcess.on('error', done);

                  // Not ideal, but we need to make sure the process is running.
                  setTimeout(() => {
                    request
                      .get(`http://localhost:${originalGatewayPort}`)
                      .end((err, res) => {
                        assert(err);
                        assert(res.unauthorized);
                        done();
                      });
                  }, GATEWAY_STARTUP_WAIT_TIME);
                });
              });
            }).catch(done);
          });
        });
      });
    });

    after(function (done) {
      childProcess.kill();
      rimraf(testGatewayConfigPath, done);
    });

    beforeEach(function (done) {
      watcher = chokidar.watch(testGatewayConfigPath, { awaitWriteFinish: true });
      watcher.on('ready', done);
    });

    afterEach(function () {
      watcher.close();
    });

    describe('reloads valid gateway.config.yml', function () {
      it('will respond with a 404 - proxy policy', function (done) {
        this.timeout(TEST_TIMEOUT);
        watcher.once('change', (evt) => {
          setTimeout(() => {
            request
              .get(`http://localhost:${originalGatewayPort}`)
              .end((err, res) => {
                assert(err);
                assert(res.clientError);
                assert.equal(res.statusCode, 404);
                done();
              });
          }, GATEWAY_STARTUP_WAIT_TIME);
        });

        testGatewayConfigData.pipelines.adminAPI.policies.shift();
        fs.writeFileSync(testGatewayConfigPath, yaml.dump(testGatewayConfigData));
      });
    });

    describe('uses previous config on reload of invalid gateway.config.yml', function () {
      it('will respond with 404 - empty proxy', function (done) {
        this.timeout(TEST_TIMEOUT);
        watcher.once('change', () => {
          request
            .get(`http://localhost:${originalGatewayPort}`)
            .end((err, res) => {
              assert(err);
              assert(res.clientError);
              assert.equal(res.statusCode, 404);
              done();
            });
        });
        // make config invalid
        fs.writeFileSync(testGatewayConfigPath, yaml.dump('{er:t4'));
      });
    });
  });
});
<commit_msg>Ignore initial change event<commit_after>const { fork } = require('child_process');
const fs = require('fs');
const path = require('path');

const assert = require('chai').assert;
const chokidar = require('chokidar');
const cpr = require('cpr');
const request = require('superagent');
const rimraf = require('rimraf');
const tmp = require('tmp');
const yaml = require('js-yaml');

const { findOpenPortNumbers } = require('../common/server-helper');

const GATEWAY_STARTUP_WAIT_TIME = 5000;
const TEST_TIMEOUT = 10000;

/*
    1) Copy config to a temp directory.
    2) Execute a child process with `process.env.EG_CONFIG_DIR` set to the temp directory.
    3) Watch the temp directory config file from the test.
    4) Do a baseline request to make sure the original gateway config is working.
    5) Write a new gateway config
    6) When the test watcher fires, make another HTTP request to confirm the new config is working.
    7) Clean up the temp directory.
*/

const baseConfigDirectory = path.join(__dirname, '..', 'fixtures', 'hot-reload');

describe('hot-reload', () => {
  describe('gateway config', () => {
    let testGatewayConfigPath = null;
    let testGatewayConfigData = null;
    let childProcess = null;
    let originalGatewayPort = null;
    let watcher = null;

    before(function (done) {
      this.timeout(TEST_TIMEOUT);
      tmp.dir((err, tempPath) => {
        if (err) {
          return done(err);
        }

        cpr(baseConfigDirectory, tempPath, (err, files) => {
          if (err) {
            return done(err);
          }

          cpr(path.join(__dirname, '../../lib/config/models'), path.join(tempPath, 'models'), (err, files) => {
            if (err) {
              return done(err);
            }

            testGatewayConfigPath = path.join(tempPath, 'gateway.config.yml');

            findOpenPortNumbers(3).then(ports => {
              fs.readFile(testGatewayConfigPath, (err, configData) => {
                if (err) {
                  return done(err);
                }

                testGatewayConfigData = yaml.load(configData);

                testGatewayConfigData.http.port = ports[0];
                testGatewayConfigData.https.port = ports[1];
                testGatewayConfigData.admin.port = ports[2];
                testGatewayConfigData.serviceEndpoints.backend.url =
                  `http://localhost:${ports[2]}`;

                originalGatewayPort = ports[0];

                fs.writeFile(testGatewayConfigPath, yaml.dump(testGatewayConfigData), (err) => {
                  if (err) {
                    return done(err);
                  }

                  const childEnv = Object.assign({}, process.env);
                  childEnv.EG_CONFIG_DIR = tempPath;

                  // Tests, by default have config watch disabled.
                  // Need to remove this paramter in the child process.
                  delete childEnv.EG_DISABLE_CONFIG_WATCH;

                  const modulePath = path.join(__dirname, '../..', 'lib', 'index.js');
                  childProcess = fork(modulePath, [], {
                    cwd: tempPath,
                    env: childEnv
                  });

                  childProcess.on('error', done);

                  // Not ideal, but we need to make sure the process is running.
                  setTimeout(() => {
                    request
                      .get(`http://localhost:${originalGatewayPort}`)
                      .end((err, res) => {
                        assert(err);
                        assert(res.unauthorized);
                        done();
                      });
                  }, GATEWAY_STARTUP_WAIT_TIME);
                });
              });
            }).catch(done);
          });
        });
      });
    });

    after(function (done) {
      childProcess.kill();
      rimraf(testGatewayConfigPath, done);
    });

    beforeEach(function (done) {
      watcher = chokidar.watch(testGatewayConfigPath, { awaitWriteFinish: true, ignoreInitial: true });
      watcher.on('ready', done);
    });

    afterEach(function () {
      watcher.close();
    });

    describe('reloads valid gateway.config.yml', function () {
      it('will respond with a 404 - proxy policy', function (done) {
        this.timeout(TEST_TIMEOUT);
        watcher.once('change', (evt) => {
          setTimeout(() => {
            request
              .get(`http://localhost:${originalGatewayPort}`)
              .end((err, res) => {
                assert(err);
                assert(res.clientError);
                assert.equal(res.statusCode, 404);
                done();
              });
          }, GATEWAY_STARTUP_WAIT_TIME);
        });

        testGatewayConfigData.pipelines.adminAPI.policies.shift();
        fs.writeFileSync(testGatewayConfigPath, yaml.dump(testGatewayConfigData));
      });
    });

    describe('uses previous config on reload of invalid gateway.config.yml', function () {
      it('will respond with 404 - empty proxy', function (done) {
        this.timeout(TEST_TIMEOUT);
        watcher.once('change', () => {
          request
            .get(`http://localhost:${originalGatewayPort}`)
            .end((err, res) => {
              assert(err);
              assert(res.clientError);
              assert.equal(res.statusCode, 404);
              done();
            });
        });
        // make config invalid
        fs.writeFileSync(testGatewayConfigPath, yaml.dump('{er:t4'));
      });
    });
  });
});
<|endoftext|>


<commit_before>var async = require('async');
var http = require('http');
var should = require('should');
var config = require('./config.js')
var server = require('./simpleServer.js');
var utils = require('./utils.js');

var serversToShutDown = [];

var consumer = require('../../lib/consumer.js');
var listener = require('../../lib/listener.js');

var HOST = config.rushServer.hostname;
var PORT = config.rushServer.port;

function executeTest(method, content, persistence, done) {
  'use strict';

  var id, options = {};
  var HEADER_NAME = 'test-header', HEADER_VALUE = 'test header 1', PATH = '/testa/testb/testc?a=b&c=d';

  options.host = HOST;
  options.port = PORT;
  options.path = PATH;
  options.headers = {};
  options.method = method;
  options.headers['content-type'] = 'application/json';
  options.headers['X-Relayer-Host'] =  config.simpleServerHostname + ':' + config.simpleServerPort;
  options.headers['X-relayer-persistence'] = persistence;
  options.headers[HEADER_NAME] = HEADER_VALUE;

  var simpleServer = server.serverListener(

      function() {
        utils.makeRequest(options, content, function(err, res) {
          should.not.exist(err);
          id = JSON.parse(res).id;
        });
      },

      function(methodUsed, headersReceived, urlUsed, bodyReceived) {

        methodUsed.should.be.equal(method);
        headersReceived.should.have.property(HEADER_NAME, HEADER_VALUE);
        urlUsed.should.be.equal(PATH);

        var checked = false;
        var interval = setInterval(function() {

          var options = { port: PORT, host: HOST,
            path: '/response/' + id, method: 'GET'};

          function checkResponse(err, data, res) {

            var JSONres = JSON.parse(data);

            if (!checked && res.statusCode !== 404 && JSONres.state === 'completed') {

              clearInterval(interval);

              if (persistence === 'BODY') {

                JSONres.should.have.property('body');
                JSONres.body.should.be.equal(content);
                JSONres.headers.should.have.property(HEADER_NAME, HEADER_VALUE);
                JSONres.should.have.property('statusCode', '200');

              } else if (persistence === 'HEADER') {

                JSONres.should.not.have.property('body');
                JSONres.should.have.property('headers');
                JSONres.headers.should.have.property(HEADER_NAME, HEADER_VALUE);
                JSONres.should.have.property('statusCode', '200');

              } else if (persistence === 'STATUS') {

                JSONres.should.not.have.property('body');
                JSONres.should.not.have.property('headers');
                JSONres.should.have.property('statusCode', '200');

              }

              checked = true;
              done();

            }
          }

          utils.makeRequest(options, '', checkResponse);

        }, 10);
      }
  );

  serversToShutDown.push(simpleServer);
}

describe('Feature: Persistence', function() {

  before(function (done) {
    listener.start(function() {
      consumer.start(done);
    });
  });

  after(function (done) {
    listener.stop(function() {
      consumer.stop(done);
    });
  });

  afterEach(function() {
    for (var i = 0; i < serversToShutDown.length; i++) {
      try {
        serversToShutDown[i].close();
      } catch (e) {

      }
    }

    serversToShutDown = [];
  });

  it('should return 404 if the persistence doesn\'t exist', function(done){
    var id = 'not_an_id';
    utils.makeRequest({host:HOST, port:PORT, path : '/response/' + id}, '', function(err, data, res) {
      should.not.exist(err);
      res.should.have.property('statusCode', 404);
      var JSONres = JSON.parse(data);
      JSONres.should.have.property('exceptionId','SVC1006');
      JSONres.should.have.property('exceptionText', 'Resource not_an_id does not exist');
      done();
    });
  });

  it('should return empty body and test-header', function(done) {
    executeTest('GET', '', 'BODY', done);
  });

  it('should return the same body', function(done) {
    executeTest('POST', 'Body Example', 'BODY', done);
  });

  it ('should return status and header. should not return body', function(done) {
    executeTest('POST', 'Body Example', 'HEADER', done);
  });

  it ('should not return body neither heraders', function(done) {
    executeTest('POST', 'Body Example', 'STATUS', done);
  });

  it('should return error headers (ENOTFOUND) OR (EADDRINFO)', function(done) {
    var id, options = {};
    options.host = HOST;
    options.port = PORT;
    options.headers = {};
    options.method = 'POST';
    options.headers['X-Relayer-Host'] = 'notAServer:8014';
    options.headers['X-relayer-persistence'] = 'BODY';
    options.headers['test-header'] = 'test header';

    async.series([
      function(callback) {
        utils.makeRequest(options, 'body request', function(err, res) {
          id = JSON.parse(res).id;

          if (!err) {
            callback(null, res);
          } else {
            callback(err, null);
          }

        });
      },

      function(callback) {

        var checked = false;
        var interval = setInterval(function() {

          var options = { port: PORT, host: HOST,
            path: '/response/' + id, method: 'GET'};

          function checkResponse(err, data, res) {

            var JSONres = JSON.parse(data);

            if (!checked && res.statusCode !== 404 && JSONres.state === 'completed') {

              clearInterval(interval);

              if (!err) {
                callback(null, JSON.parse(data));
              } else {
                callback(err, null);
              }

              checked = true;
            }
          }

          utils.makeRequest(options, '', checkResponse);

        }, 10);
      }
    ], function(err, res) {
      var resGet = res[1];

      resGet.should.have.property('exception');
      resGet['exception'].should.have.property('exceptionId', 'SVC Relayed Host Error');
      resGet['exception'].should.have.property('exceptionText');
      resGet['exception']['exceptionText'].should.match(/(ENOTFOUND|EADDRINFO)/);

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

<commit_msg>Remove unnecesary dependency<commit_after>var async = require('async');
var should = require('should');
var config = require('./config.js')
var server = require('./simpleServer.js');
var utils = require('./utils.js');

var serversToShutDown = [];

var consumer = require('../../lib/consumer.js');
var listener = require('../../lib/listener.js');

var HOST = config.rushServer.hostname;
var PORT = config.rushServer.port;

function executeTest(method, content, persistence, done) {
  'use strict';

  var id, options = {};
  var HEADER_NAME = 'test-header', HEADER_VALUE = 'test header 1', PATH = '/testa/testb/testc?a=b&c=d';

  options.host = HOST;
  options.port = PORT;
  options.path = PATH;
  options.headers = {};
  options.method = method;
  options.headers['content-type'] = 'application/json';
  options.headers['X-Relayer-Host'] =  config.simpleServerHostname + ':' + config.simpleServerPort;
  options.headers['X-relayer-persistence'] = persistence;
  options.headers[HEADER_NAME] = HEADER_VALUE;

  var simpleServer = server.serverListener(

      function() {
        utils.makeRequest(options, content, function(err, res) {
          should.not.exist(err);
          id = JSON.parse(res).id;
        });
      },

      function(methodUsed, headersReceived, urlUsed, bodyReceived) {

        methodUsed.should.be.equal(method);
        headersReceived.should.have.property(HEADER_NAME, HEADER_VALUE);
        urlUsed.should.be.equal(PATH);

        var checked = false;
        var interval = setInterval(function() {

          var options = { port: PORT, host: HOST,
            path: '/response/' + id, method: 'GET'};

          function checkResponse(err, data, res) {

            var JSONres = JSON.parse(data);

            if (!checked && res.statusCode !== 404 && JSONres.state === 'completed') {

              clearInterval(interval);

              if (persistence === 'BODY') {

                JSONres.should.have.property('body');
                JSONres.body.should.be.equal(content);
                JSONres.headers.should.have.property(HEADER_NAME, HEADER_VALUE);
                JSONres.should.have.property('statusCode', '200');

              } else if (persistence === 'HEADER') {

                JSONres.should.not.have.property('body');
                JSONres.should.have.property('headers');
                JSONres.headers.should.have.property(HEADER_NAME, HEADER_VALUE);
                JSONres.should.have.property('statusCode', '200');

              } else if (persistence === 'STATUS') {

                JSONres.should.not.have.property('body');
                JSONres.should.not.have.property('headers');
                JSONres.should.have.property('statusCode', '200');

              }

              checked = true;
              done();

            }
          }

          utils.makeRequest(options, '', checkResponse);

        }, 10);
      }
  );

  serversToShutDown.push(simpleServer);
}

describe('Feature: Persistence', function() {

  before(function (done) {
    listener.start(function() {
      consumer.start(done);
    });
  });

  after(function (done) {
    listener.stop(function() {
      consumer.stop(done);
    });
  });

  afterEach(function() {
    for (var i = 0; i < serversToShutDown.length; i++) {
      try {
        serversToShutDown[i].close();
      } catch (e) {

      }
    }

    serversToShutDown = [];
  });

  it('should return 404 if the persistence doesn\'t exist', function(done){
    var id = 'not_an_id';
    utils.makeRequest({host:HOST, port:PORT, path : '/response/' + id}, '', function(err, data, res) {
      should.not.exist(err);
      res.should.have.property('statusCode', 404);
      var JSONres = JSON.parse(data);
      JSONres.should.have.property('exceptionId','SVC1006');
      JSONres.should.have.property('exceptionText', 'Resource not_an_id does not exist');
      done();
    });
  });

  it('should return empty body and test-header', function(done) {
    executeTest('GET', '', 'BODY', done);
  });

  it('should return the same body', function(done) {
    executeTest('POST', 'Body Example', 'BODY', done);
  });

  it ('should return status and header. should not return body', function(done) {
    executeTest('POST', 'Body Example', 'HEADER', done);
  });

  it ('should not return body neither heraders', function(done) {
    executeTest('POST', 'Body Example', 'STATUS', done);
  });

  it('should return error headers (ENOTFOUND) OR (EADDRINFO)', function(done) {
    var id, options = {};
    options.host = HOST;
    options.port = PORT;
    options.headers = {};
    options.method = 'POST';
    options.headers['X-Relayer-Host'] = 'notAServer:8014';
    options.headers['X-relayer-persistence'] = 'BODY';
    options.headers['test-header'] = 'test header';

    async.series([
      function(callback) {
        utils.makeRequest(options, 'body request', function(err, res) {
          id = JSON.parse(res).id;

          if (!err) {
            callback(null, res);
          } else {
            callback(err, null);
          }

        });
      },

      function(callback) {

        var checked = false;
        var interval = setInterval(function() {

          var options = { port: PORT, host: HOST,
            path: '/response/' + id, method: 'GET'};

          function checkResponse(err, data, res) {

            var JSONres = JSON.parse(data);

            if (!checked && res.statusCode !== 404 && JSONres.state === 'completed') {

              clearInterval(interval);

              if (!err) {
                callback(null, JSON.parse(data));
              } else {
                callback(err, null);
              }

              checked = true;
            }
          }

          utils.makeRequest(options, '', checkResponse);

        }, 10);
      }
    ], function(err, res) {
      var resGet = res[1];

      resGet.should.have.property('exception');
      resGet['exception'].should.have.property('exceptionId', 'SVC Relayed Host Error');
      resGet['exception'].should.have.property('exceptionText');
      resGet['exception']['exceptionText'].should.match(/(ENOTFOUND|EADDRINFO)/);

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


<commit_before>'use strict';
const expect = require('chai').expect;
const Business = require('../../src/faker/business');
const data = require('../../data/business.json');

describe('Business', () => {
  describe('#creditCardNumber', () => {
    it('should return a credit card number', () => {
      [...Array(100).keys()].forEach(_ => {
        expect(Business.creditCardNumber()).to.be.oneOf(data['creditCardNumbers']);
      });
    });
  });

  describe('#creditCardExpiryDate', () => {
    it('should return a date in the future', () => {
      [...Array(100).keys()].forEach(_ => {
        expect(Business.creditCardExpiryDate()).to.be.above(new Date());
      });
    });
  });

  describe('#creditCardType', () => {
    it('should return a credit card type', () => {
      [...Array(100).keys()].forEach(_ => {
        expect(Business.creditCardType()).to.be.oneOf(data['creditCardTypes']);
      });
    });
  });
});
<commit_msg>Fixed creditCardExpiryDate test.<commit_after>'use strict';
const chai = require('chai');
const { expect } = chai;
const Business = require('../../src/faker/business');
const data = require('../../data/business.json');

chai.use(require('chai-datetime'));

describe('Business', () => {
  describe('#creditCardNumber', () => {
    it('should return a credit card number', () => {
      [...Array(100).keys()].forEach(_ => {
        expect(Business.creditCardNumber()).to.be.oneOf(data['creditCardNumbers']);
      });
    });
  });

  describe('#creditCardExpiryDate', () => {
    it('should return a date in the future', () => {
      [...Array(100).keys()].forEach(_ => {
        expect(Business.creditCardExpiryDate()).to.be.afterDate(new Date());
      });
    });
  });

  describe('#creditCardType', () => {
    it('should return a credit card type', () => {
      [...Array(100).keys()].forEach(_ => {
        expect(Business.creditCardType()).to.be.oneOf(data['creditCardTypes']);
      });
    });
  });
});
<|endoftext|>


<commit_before>var util = require('util'),
    should = require('should'),
    ineed = require('../../index'),
    ApiHost = require('../../lib/api_host');

function noop() {
    //Do nothing =)
}

//Tests
describe('iwant.using()', function () {

    it('should extend .collect', function () {
        var wordsPlugin = {
            name: 'words',
            extends: 'collect',

            init: function () {
                this.collection = [];
            },

            onText: function (text) {
                var words = text.split(' ').filter(function (word) {
                    return word.length;
                });
                this.collection = this.collection.concat(words);
            },

            getCollection: function () {
                return this.collection;
            }
        };

        var html = '
Yo dawgi
 heard you  like plugins ',
            expected = ['Yo', 'dawg', 'i', 'heard', 'you', 'like', 'plugins'],
            result = ineed.using(wordsPlugin).collect.words.fromHtml(html);

        result.words.should.eql(expected);
    });

    it('should extend .reprocess', function () {
        var wordsPlugin = {
            name: 'answer',
            extends: 'reprocess',

            init: function (ctx, replacer) {
                this.replacer = replacer;
            },

            onText: function (text) {
                text = text.replace(/42/g, this.replacer);

                return text;
            }
        };

        var html = '
Theanswer
 is 42',
            expected = '
Theanswer
 is 24',
            result = ineed.using(wordsPlugin).reprocess.answer(function () {
                return '24';
            }).fromHtml(html);

        result.should.eql(expected);
    });

    describe('Plugin validation', function () {

        it('should throw error if .name is missing', function () {
            (function () {
                ineed.using({
                    extends: 'reprocess',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_NAME_PROPERTY);
        });

        it('should throw error if .extends is missing', function () {
            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_EXTENDS_PROPERTY);
        });

        it('should throw error if .getCollection() is missing', function () {
            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_GET_COLLECTION_METHOD);

            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    getCollection: 'test',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_GET_COLLECTION_METHOD);

            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'reprocess',
                    init: noop
                });
            }).should.not.throw();
        });

        it('should throw error if .init() is missing', function () {
            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    getCollection: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_INIT_METHOD);

            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    getCollection: noop,
                    init: 'test'
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_INIT_METHOD);
        });

        it('should throw error if plugin name is already used', function () {
            var collectPlugin = {
                    name: 'collect_plugin',
                    extends: 'collect',
                    init: noop,
                    getCollection: function () {
                        return null;
                    }
                },

                reprocessPlugin = {
                    name: 'reprocess_plugin',
                    extends: 'reprocess',
                    init: noop
                };

            (function () {
                ineed
                    .using(collectPlugin)
                    .using(reprocessPlugin)
                    .using(collectPlugin);
            }).should.throw(util.format(ApiHost.ERR_DUPLICATE_PLUGIN_NAME, 'collect_plugin', 'collect'));

            (function () {
                ineed
                    .using(collectPlugin)
                    .using(reprocessPlugin)
                    .using(reprocessPlugin);
            }).should.throw(util.format(ApiHost.ERR_DUPLICATE_PLUGIN_NAME, 'reprocess_plugin', 'reprocess'));

            (function () {
                ineed
                    .using(collectPlugin)
                    .using({
                        name: 'collect_plugin',
                        extends: 'reprocess',
                        init: noop
                    })
            }).should.not.throw();
        });
    });
});
<commit_msg>Test that .using() creates new ApiHost<commit_after>var util = require('util'),
    should = require('should'),
    ineed = require('../../index'),
    ApiHost = require('../../lib/api_host');

function noop() {
    //Do nothing =)
}

//Tests
describe('iwant.using()', function () {

    it('should extend .collect', function () {
        var wordsPlugin = {
            name: 'words',
            extends: 'collect',

            init: function () {
                this.collection = [];
            },

            onText: function (text) {
                var words = text.split(' ').filter(function (word) {
                    return word.length;
                });
                this.collection = this.collection.concat(words);
            },

            getCollection: function () {
                return this.collection;
            }
        };

        var html = '
Yo dawgi
 heard you  like plugins ',
            expected = ['Yo', 'dawg', 'i', 'heard', 'you', 'like', 'plugins'],
            result = ineed.using(wordsPlugin).collect.words.fromHtml(html);

        result.words.should.eql(expected);
    });

    it('should extend .reprocess', function () {
        var wordsPlugin = {
            name: 'answer',
            extends: 'reprocess',

            init: function (ctx, replacer) {
                this.replacer = replacer;
            },

            onText: function (text) {
                text = text.replace(/42/g, this.replacer);

                return text;
            }
        };

        var html = '
Theanswer
 is 42',
            expected = '
Theanswer
 is 24',
            result = ineed.using(wordsPlugin).reprocess.answer(function () {
                return '24';
            }).fromHtml(html);

        result.should.eql(expected);
    });

    it('should create new instance of the API host', function () {
        var newInstance = ineed.using({
            name: 'coolPlugin',
            extends: 'reprocess',
            init: noop
        });

        ineed.should.not.eql(newInstance);
        ineed.reprocess.should.not.have.property('coolPlugin');
        newInstance.reprocess.should.have.property('coolPlugin');
    });

    describe('Plugin validation', function () {

        it('should throw error if .name is missing', function () {
            (function () {
                ineed.using({
                    extends: 'reprocess',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_NAME_PROPERTY);
        });

        it('should throw error if .extends is missing', function () {
            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_EXTENDS_PROPERTY);
        });

        it('should throw error if .getCollection() is missing', function () {
            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_GET_COLLECTION_METHOD);

            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    getCollection: 'test',
                    init: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_GET_COLLECTION_METHOD);

            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'reprocess',
                    init: noop
                });
            }).should.not.throw();
        });

        it('should throw error if .init() is missing', function () {
            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    getCollection: noop
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_INIT_METHOD);

            (function () {
                ineed.using({
                    name: 'coolPlugin',
                    extends: 'collect',
                    getCollection: noop,
                    init: 'test'
                });
            }).should.throw(ApiHost.ERR_PLUGIN_MISSING_INIT_METHOD);
        });

        it('should throw error if plugin name is already used', function () {
            var collectPlugin = {
                    name: 'collect_plugin',
                    extends: 'collect',
                    init: noop,
                    getCollection: function () {
                        return null;
                    }
                },

                reprocessPlugin = {
                    name: 'reprocess_plugin',
                    extends: 'reprocess',
                    init: noop
                };

            (function () {
                ineed
                    .using(collectPlugin)
                    .using(reprocessPlugin)
                    .using(collectPlugin);
            }).should.throw(util.format(ApiHost.ERR_DUPLICATE_PLUGIN_NAME, 'collect_plugin', 'collect'));

            (function () {
                ineed
                    .using(collectPlugin)
                    .using(reprocessPlugin)
                    .using(reprocessPlugin);
            }).should.throw(util.format(ApiHost.ERR_DUPLICATE_PLUGIN_NAME, 'reprocess_plugin', 'reprocess'));

            (function () {
                ineed
                    .using(collectPlugin)
                    .using({
                        name: 'collect_plugin',
                        extends: 'reprocess',
                        init: noop
                    })
            }).should.not.throw();
        });
    });
});
<|endoftext|>


<commit_before>(function($, window){

    var settings = {};

    var methods = {

        init : function(options)
        {
            var key = this.selector;

            settings[key] = $.extend( {
                addSelector: '[data-addfield="collection"]',
                removeSelector: '[data-removefield="collection"]',
                wrapperTag: 'ul',
                elementWrapperTag: 'li'
            }, options);

            return this.each(function(index, element) {

                var $element = $(element);

                $($element, window).on('click', settings[key]['addSelector'], function(event) {

                    event.preventDefault();

                    $link = $(event.target);

                    var $collection = $('#'+ $link.attr('data-collection'));
                    var $wrapper = $collection.find(settings[key]['wrapperTag']);
                    var count = $wrapper.find(settings[key]['elementWrapperTag']).size();

                    var newWidget = $link.attr('data-prototype') ? $link.attr('data-prototype') : $collection.attr('data-prototype');

                    // Check if an element with this ID already exists.
                    // If it does, increase the count by one and try again
                    var newName = newWidget.match(/id="(.*?)"/);
                    while ($('#' + newName[1].replace(/__name__/g, count)).size() > 0) {
                        count++;
                    }
                    newWidget = newWidget.replace(/__name__/g, count);
                    newWidget = newWidget.replace(/__id__/g, newName[1].replace(/__name__/g, count));

                    var elementWrappers = '<' + settings[key]['elementWrapperTag'] + '>';
                    elementWrappers += '</' + settings[key]['elementWrapperTag'] + '>';

                    var $elementWrapper = $(elementWrappers).html(newWidget);
                    $elementWrapper.appendTo($wrapper);
                });

                $($element, window).on('click', settings[key]['removeSelector'], function(event) {

                    event.preventDefault();

                    $link = $(event.target);

                    var $widget = $('#'+ $link.attr('data-field'));
                    var $elementWrapper = $widget.closest(settings[key]['elementWrapperTag']);

                    $elementWrapper.remove();
                });
            });
        }
    };

    $.fn.saxulumCollection = function(method) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jquery.saxulum-collection.js' );
        }
    };

})(jQuery, window);<commit_msg>add event for add and remove<commit_after>(function($, window){

    var settings = {};

    var methods = {

        init : function(options)
        {
            var key = this.selector;

            settings[key] = $.extend( {
                addSelector: '[data-addfield="collection"]',
                removeSelector: '[data-removefield="collection"]',
                wrapperTag: 'ul',
                elementWrapperTag: 'li'
            }, options);

            return this.each(function(index, element) {

                var $element = $(element);

                $($element, window).on('click', settings[key]['addSelector'], function(event) {

                    event.preventDefault();

                    $link = $(event.target);

                    var $collection = $('#'+ $link.attr('data-collection'));
                    var $wrapper = $collection.find(settings[key]['wrapperTag']);
                    var count = $wrapper.find(settings[key]['elementWrapperTag']).size();

                    var newWidget = $link.attr('data-prototype') ? $link.attr('data-prototype') : $collection.attr('data-prototype');

                    // Check if an element with this ID already exists.
                    // If it does, increase the count by one and try again
                    var newName = newWidget.match(/id="(.*?)"/);
                    while ($('#' + newName[1].replace(/__name__/g, count)).size() > 0) {
                        count++;
                    }
                    newWidget = newWidget.replace(/__name__/g, count);
                    newWidget = newWidget.replace(/__id__/g, newName[1].replace(/__name__/g, count));

                    var elementWrappers = '<' + settings[key]['elementWrapperTag'] + '>';
                    elementWrappers += '</' + settings[key]['elementWrapperTag'] + '>';

                    var $elementWrapper = $(elementWrappers).html(newWidget);
                    $elementWrapper.appendTo($wrapper);

                    $.trigger('saxulum-collection.add');
                });

                $($element, window).on('click', settings[key]['removeSelector'], function(event) {

                    event.preventDefault();

                    $link = $(event.target);

                    var $widget = $('#'+ $link.attr('data-field'));
                    var $elementWrapper = $widget.closest(settings[key]['elementWrapperTag']);

                    $elementWrapper.remove();

                    $.trigger('saxulum-collection.remove');
                });
            });
        }
    };

    $.fn.saxulumCollection = function(method) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jquery.saxulum-collection.js' );
        }
    };

})(jQuery, window);<|endoftext|>