<commit_before>describe('Interface', function () {
  var map;
  var el;

  beforeEach('initialize map', function () {
    el = document.createElement('div');
    // DOM needs to be visible: appended to the body and have dimensions
    // in order for .focus() to work properly
    el.style.cssText = 'position: absolute; left: 0; top: 0; width: 100%; height: 100%;';
    document.body.appendChild(el);
    map = L.map(el);
  });

  afterEach('destroy map', function () {
    map.remove();
    document.body.removeChild(el);
  });

  describe('Basic interactions', function () {
    it('focuses on the input when I click on the geocoder', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      happen.click(geocoder.getContainer());
      expect(document.activeElement).to.be(geocoder._input);
    });
  });

  describe('The × button (reset)', function () {
    it('should not be visible when control is first added', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(true);
    });

    it('should be visible when input has 1 character', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      // Simulates input action
      geocoder._input.focus();
      geocoder._input.value = 'a';
      happen.keyup(geocoder._input);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(false);
    });

    it('should be visible when input has 2 characters', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      // Simulates input action
      geocoder._input.focus();
      geocoder._input.value = 'bb';
      happen.keyup(geocoder._input);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(false);
    });

    it('should reset input when clicked', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);

      // Simulates input action
      geocoder._input.focus();
      geocoder._input.value = 'sometext';
      happen.click(geocoder._close);

      expect(geocoder._input.value.length).to.be(0);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(true);
      expect(geocoder.markers).to.be.empty();
      expect(geocoder._results.style.display).to.be('none');
      expect(geocoder._results.innerHTML.length).to.be(0);
    });

    it('fires `reset` event', function () {
      var geocoder = new L.Control.Geocoder();
      var onReset = sinon.spy();

      geocoder.addTo(map);
      geocoder.on('reset', onReset);

      happen.click(geocoder._close);

      expect(onReset.called).to.be(true);
      expect(onReset.callCount).to.be.lessThan(2);
    });
  });

  describe('Interacting with results list', function () {
    var results;
    var geocoder;

    before('load the dummy results', function (done) {
      loadJSON('fixtures/search.json', function (response) {
        results = JSON.parse(response);
        done();
      });
    });

    beforeEach('simulate input and results', function () {
      geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      geocoder.expand();
      geocoder.showResults(results.features);
    });

    it('has no highlighted result at first', function () {
      expect(document.querySelector('.leaflet-pelias-selected')).to.be.null;
    });

    it('highlights the first result when I press down', function () {
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[0]);
    });

    it('highlights the last result when I press up', function () {
      happen.keydown(geocoder._input, { keyCode: 38 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[9]);
    });

    it('highlights the next item when I press down twice', function () {
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[1]);
    });

    it('highlights the correct result after a bunch of up/down presses', function () {
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[0]);
    });

    it('selects the currently highlighted result when I press enter', function () {
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      var selectedEl = document.querySelector('.leaflet-pelias-selected');
      happen.keydown(geocoder._input, { keyCode: 13 });
      expect(selectedEl.feature).to.eql(onSelect.args[0][0].feature);
    });

    it('selects a result when I click it', function () {
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      var selectedEl = document.querySelectorAll('.leaflet-pelias-result')[5];
      happen.click(selectedEl);
      expect(selectedEl.feature).to.eql(onSelect.args[0][0].feature);
    });

    it('pans the map when a result is highlighted');
    it('does not pan the map when a result is highlighted');

    it('fires `highlight` event', function () {
      // Also checks that `select` is not fired
      var onHighlight = sinon.spy();
      var onSelect = sinon.spy();
      geocoder.on('highlight', onHighlight);
      geocoder.on('select', onSelect);
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(onHighlight.called).to.be(true);
      expect(onSelect.called).to.be(false);
    });

    it('fires `select` event', function () {
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 13 });
      expect(onSelect.called).to.be(true);
    });
  });

  describe('Actions that toggle expanded state', function () {
    it.skip('does not collapse if: map is clicked, and geocoder contains input', function () {
      var geocoder = new L.Control.Geocoder();
      var onCollapse = sinon.spy();

      geocoder.addTo(map);
      geocoder.on('collapse', onCollapse);

      // Simulates input
      geocoder.expand();
      geocoder._input.value = 'a';

      // Click the map
      // TODO: This is not actually clicking the map :(
      // happen.click(map);
      expect(onCollapse.called).to.be(false);
      expect(geocoder.getContainer().classList.contains('leaflet-pelias-expanded')).to.be(true);
    });

    it.skip('collapses if: map is clicked, and geocoder is blank', function () {
      var geocoder = new L.Control.Geocoder();
      var onCollapse = sinon.spy();

      geocoder.addTo(map);
      geocoder.on('collapse', onCollapse);
      geocoder.expand();

      // Click the map
      // TODO: This is not actually clicking the map :(
      // happen.click(map);
      expect(onCollapse.called).to.be(true);
      expect(geocoder.getContainer().classList.contains('leaflet-pelias-expanded')).to.be(false);
    });

    it('collapses if: map is panned, and a result is highlighted');
  });
});
<commit_msg>Add tests for map panning when results are highlighted<commit_after>describe('Interface', function () {
  var map;
  var el;

  beforeEach('initialize map', function () {
    el = document.createElement('div');
    // DOM needs to be visible: appended to the body and have dimensions
    // in order for .focus() to work properly
    el.style.cssText = 'position: absolute; left: 0; top: 0; width: 100%; height: 100%;';
    document.body.appendChild(el);
    map = L.map(el);
  });

  afterEach('destroy map', function () {
    map.remove();
    document.body.removeChild(el);
  });

  describe('Basic interactions', function () {
    it('focuses on the input when I click on the geocoder', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      happen.click(geocoder.getContainer());
      expect(document.activeElement).to.be(geocoder._input);
    });
  });

  describe('The × button (reset)', function () {
    it('should not be visible when control is first added', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(true);
    });

    it('should be visible when input has 1 character', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      // Simulates input action
      geocoder._input.focus();
      geocoder._input.value = 'a';
      happen.keyup(geocoder._input);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(false);
    });

    it('should be visible when input has 2 characters', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      // Simulates input action
      geocoder._input.focus();
      geocoder._input.value = 'bb';
      happen.keyup(geocoder._input);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(false);
    });

    it('should reset input when clicked', function () {
      var geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);

      // Simulates input action
      geocoder._input.focus();
      geocoder._input.value = 'sometext';
      happen.click(geocoder._close);

      expect(geocoder._input.value.length).to.be(0);
      expect(geocoder._close.classList.contains('leaflet-pelias-hidden')).to.be(true);
      expect(geocoder.markers).to.be.empty();
      expect(geocoder._results.style.display).to.be('none');
      expect(geocoder._results.innerHTML.length).to.be(0);
    });

    it('fires `reset` event', function () {
      var geocoder = new L.Control.Geocoder();
      var onReset = sinon.spy();

      geocoder.addTo(map);
      geocoder.on('reset', onReset);

      happen.click(geocoder._close);

      expect(onReset.called).to.be(true);
      expect(onReset.callCount).to.be.lessThan(2);
    });
  });

  describe('Input element', function () {
    it('performs a search when I press enter');
    it('does not perform a search when the input is blank');
    it('does not perform a search when an element is highlighted');
    it('performs autocomplete when enabled');
    it('does not perform autocomplete when disabled');
    it('clears current input and results when I press enter');
  });

  describe('Results list', function () {
    var results;
    var geocoder;

    before('load the dummy results', function (done) {
      loadJSON('fixtures/search.json', function (response) {
        results = JSON.parse(response);
        done();
      });
    });

    beforeEach('simulate input and results', function () {
      geocoder = new L.Control.Geocoder();
      geocoder.addTo(map);
      geocoder.expand();
      geocoder.showResults(results.features);
    });

    it('has no highlighted result at first', function () {
      expect(document.querySelector('.leaflet-pelias-selected')).to.be.null;
    });

    it('highlights the first result when I press down', function () {
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[0]);
    });

    it('highlights the last result when I press up', function () {
      happen.keydown(geocoder._input, { keyCode: 38 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[9]);
    });

    it('highlights the next item when I press down twice', function () {
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[1]);
    });

    it('highlights the correct result after a bunch of up/down presses', function () {
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 38 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(document.querySelector('.leaflet-pelias-selected')).to.be(document.querySelectorAll('.leaflet-pelias-result')[0]);
    });

    it('selects the currently highlighted result when I press enter', function () {
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 40 });
      var selectedEl = document.querySelector('.leaflet-pelias-selected');
      happen.keydown(geocoder._input, { keyCode: 13 });
      expect(selectedEl.feature).to.eql(onSelect.args[0][0].feature);
    });

    it('selects a result when I click it', function () {
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      var selectedEl = document.querySelectorAll('.leaflet-pelias-result')[5];
      happen.click(selectedEl);
      expect(selectedEl.feature).to.eql(onSelect.args[0][0].feature);
    });

    it('pans the map when a result is highlighted', function () {
      var selectedEl, mapCenter, coords;
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      map.setView([20, 20], 10);

      // First pan
      happen.keydown(geocoder._input, { keyCode: 40 });
      selectedEl = document.querySelector('.leaflet-pelias-selected');
      mapCenter = map.getCenter();
      coords = selectedEl.feature.geometry.coordinates;
      expect(mapCenter.lat).to.be(coords[1]);
      expect(mapCenter.lng).to.be(coords[0]);

      // Second pan
      happen.keydown(geocoder._input, { keyCode: 40 });
      selectedEl = document.querySelector('.leaflet-pelias-selected');
      mapCenter = map.getCenter();
      coords = selectedEl.feature.geometry.coordinates;
      expect(mapCenter.lat).to.be(coords[1]);
      expect(mapCenter.lng).to.be(coords[0]);
    });

    it('does not pan the map when a result is highlighted', function () {
      var selectedEl, mapCenter, coords;
      geocoder.options.panToPoint = false;
      map.setView([20, 20], 10);

      // First pan
      happen.keydown(geocoder._input, { keyCode: 40 });
      selectedEl = document.querySelector('.leaflet-pelias-selected');
      mapCenter = map.getCenter();
      coords = selectedEl.feature.geometry.coordinates;
      expect(mapCenter.lat).to.not.be(coords[1]);
      expect(mapCenter.lng).to.not.be(coords[0]);

      // Second pan
      happen.keydown(geocoder._input, { keyCode: 40 });
      selectedEl = document.querySelector('.leaflet-pelias-selected');
      mapCenter = map.getCenter();
      coords = selectedEl.feature.geometry.coordinates;
      expect(mapCenter.lat).to.not.be(coords[1]);
      expect(mapCenter.lng).to.not.be(coords[0]);
    });

    it('fires `highlight` event', function () {
      // Also checks that `select` is not fired
      var onHighlight = sinon.spy();
      var onSelect = sinon.spy();
      geocoder.on('highlight', onHighlight);
      geocoder.on('select', onSelect);
      happen.keydown(geocoder._input, { keyCode: 40 });
      expect(onHighlight.called).to.be(true);
      expect(onSelect.called).to.be(false);
    });

    it('fires `select` event', function () {
      var onSelect = sinon.spy();
      geocoder.on('select', onSelect);
      happen.keydown(geocoder._input, { keyCode: 40 });
      happen.keydown(geocoder._input, { keyCode: 13 });
      expect(onSelect.called).to.be(true);
    });
  });

  describe('Actions that toggle expanded state', function () {
    it.skip('does not collapse if: map is clicked, and geocoder contains input', function () {
      var geocoder = new L.Control.Geocoder();
      var onCollapse = sinon.spy();

      geocoder.addTo(map);
      geocoder.on('collapse', onCollapse);

      // Simulates input
      geocoder.expand();
      geocoder._input.value = 'a';

      // Click the map
      // TODO: This is not actually clicking the map :(
      // happen.click(map);
      expect(onCollapse.called).to.be(false);
      expect(geocoder.getContainer().classList.contains('leaflet-pelias-expanded')).to.be(true);
    });

    it.skip('collapses if: map is clicked, and geocoder is blank', function () {
      var geocoder = new L.Control.Geocoder();
      var onCollapse = sinon.spy();

      geocoder.addTo(map);
      geocoder.on('collapse', onCollapse);
      geocoder.expand();

      // Click the map
      // TODO: This is not actually clicking the map :(
      // happen.click(map);
      expect(onCollapse.called).to.be(true);
      expect(geocoder.getContainer().classList.contains('leaflet-pelias-expanded')).to.be(false);
    });

    it('collapses if: map is dragged, and a result is highlighted');
  });
});
<|endoftext|>


<commit_before>"use strict";
var sdk = require("../..");
var WebStorageStore = sdk.WebStorageStore;
var Room = sdk.Room;
var utils = require("../test-utils");

function MockStorageApi() {
    this.data = {};
    this.keys = [];
    this.length = 0;
}
MockStorageApi.prototype = {
    setItem: function(k, v) {
        this.data[k] = v;
        this._recalc();
    },
    getItem: function(k) {
        return this.data[k] || null;
    },
    removeItem: function(k) {
        delete this.data[k];
        this._recalc();
    },
    key: function(index) {
        return this.keys[index];
    },
    _recalc: function() {
        var keys = [];
        for (var k in this.data) {
            if (!this.data.hasOwnProperty(k)) { continue; }
            keys.push(k);
        }
        this.keys = keys;
        this.length = keys.length;
    }
};

describe("WebStorageStore", function() {
    var store, room;
    var roomId = "!foo:bar";
    var userId = "@alice:bar";
    var mockStorageApi;
    var batchNum = 3;

    beforeEach(function() {
        utils.beforeEach(this);
        mockStorageApi = new MockStorageApi();
        store = new WebStorageStore(mockStorageApi, batchNum);
        room = new Room(roomId);
    });

    describe("storeRoom", function() {
        it("should persist the room state correctly", function() {
            var stateEvents = [
                utils.mkEvent({
                    event: true, type: "m.room.create", user: userId, room: roomId,
                    content: {
                        creator: userId
                    }
                }),
                utils.mkMembership({
                    event: true, user: userId, room: roomId, mship: "join"
                })
            ];
            room.currentState.setStateEvents(stateEvents);
            store.storeRoom(room);
            var storedEvents = mockStorageApi.getItem(
                "room_" + roomId + "_state"
            ).events;
            expect(storedEvents["m.room.create"][""]).toEqual(stateEvents[0].event);
        });

        xit("should persist timeline events correctly", function() {

        });
    });
});
<commit_msg>Linting.<commit_after>"use strict";
var sdk = require("../..");
var WebStorageStore = sdk.WebStorageStore;
var Room = sdk.Room;
var utils = require("../test-utils");

function MockStorageApi() {
    this.data = {};
    this.keys = [];
    this.length = 0;
}
MockStorageApi.prototype = {
    setItem: function(k, v) {
        this.data[k] = v;
        this._recalc();
    },
    getItem: function(k) {
        return this.data[k] || null;
    },
    removeItem: function(k) {
        delete this.data[k];
        this._recalc();
    },
    key: function(index) {
        return this.keys[index];
    },
    _recalc: function() {
        var keys = [];
        for (var k in this.data) {
            if (!this.data.hasOwnProperty(k)) { continue; }
            keys.push(k);
        }
        this.keys = keys;
        this.length = keys.length;
    }
};

describe("WebStorageStore", function() {
    var store, room;
    var roomId = "!foo:bar";
    var userId = "@alice:bar";
    var mockStorageApi;
    var batchNum = 3;

    beforeEach(function() {
        utils.beforeEach(this);
        mockStorageApi = new MockStorageApi();
        store = new WebStorageStore(mockStorageApi, batchNum);
        room = new Room(roomId);
    });

    describe("storeRoom", function() {
        it("should persist the room state correctly", function() {
            var stateEvents = [
                utils.mkEvent({
                    event: true, type: "m.room.create", user: userId, room: roomId,
                    content: {
                        creator: userId
                    }
                }),
                utils.mkMembership({
                    event: true, user: userId, room: roomId, mship: "join"
                })
            ];
            room.currentState.setStateEvents(stateEvents);
            store.storeRoom(room);
            var storedEvents = mockStorageApi.getItem(
                "room_" + roomId + "_state"
            ).events;
            expect(storedEvents["m.room.create"][""]).toEqual(stateEvents[0].event);
        });

        xit("should persist timeline events correctly", function() {

        });
    });
});
<|endoftext|>


<commit_before>var codeName = require('../../lib/utils/code-name');

describe("code-name", function() {
  describe("getAbsoluteCodeName", function() {
    it("returns an absolute name given a doc and name in the same module and componentType", function() {
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'ngClass'))
        .toEqual('module:ng.directive:ngClass');

      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');

      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'module:ng.directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');
    });

    it("returns an absolute name given a doc and name in the same module but different componentType", function() {
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');

      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'module:ng.directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');
    });

    it("returns an absolute name given a doc and name in a different module", function() {
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'module:ngRoute.directive:ngView'))
        .toEqual('module:ngRoute.directive:ngView');
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'module:ngRoute.$route'))
        .toEqual('module:ngRoute.$route');
    });
  });

  xdescribe("relativeName", function() {
    it("returns an relative name given a doc and an absolute name", function() {
      expect(codeName.relativeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'module:ng.directive:ngClass'))
        .toEqual('ngClass');

      expect(codeName.relativeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'module:ng.filter:currency'))
        .toEqual('filter:currency');
    });
  });

  describe("getLinkInfo", function() {
    describe('for real urls', function() {
      it("should replace urls containing slashes with HTML anchors to the same url", function() {
        var someDoc = { };

        expect(codeName.getLinkInfo(someDoc, '/some/absolute/url')).toEqual({ url: "/some/absolute/url", title: "url", type: 'url', anchorElement : 'url'});
        expect(codeName.getLinkInfo(someDoc, 'some/relative/url')).toEqual({ url: "some/relative/url", title: "url", type: 'url', anchorElement : 'url'});
        expect(codeName.getLinkInfo(someDoc, '../some/other/relative/url')).toEqual({ url: "../some/other/relative/url", title: "url", type: 'url', anchorElement : 'url'});
        expect(codeName.getLinkInfo(someDoc, 'http://www.google.com')).toEqual({ url: "http://www.google.com", title: "www.google.com", type: 'url', anchorElement : 'www.google.com'});

        expect(codeName.getLinkInfo(someDoc, '/some/absolute/url', 'some link')).toEqual({ url: "/some/absolute/url", title: "some link", type: 'url', anchorElement : 'some link'});
        expect(codeName.getLinkInfo(someDoc, 'some/relative/url', 'some other link')).toEqual({ url: "some/relative/url", title: "some other link", type: 'url', anchorElement : 'some other link'});
        expect(codeName.getLinkInfo(someDoc, '../some/other/relative/url', 'some link')).toEqual({ url: "../some/other/relative/url", title: "some link", type: 'url', anchorElement : 'some link'});
        expect(codeName.getLinkInfo(someDoc, 'http://www.google.com', 'Google')).toEqual({ url: "http://www.google.com", title: "Google", type: 'url', anchorElement : 'Google'});
      });
    });

    describe("for code references", function() {
      var someDoc;

      beforeEach(function() {
        someDoc = { module: 'ng', name:'ngClass', componentType:'directive', section: 'api' };
      });

      it("should replace relative references to code in the current module with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'ngShow').anchorElement).toEqual('ngShow');
        expect(codeName.getLinkInfo(someDoc, 'directive:ngShow').anchorElement).toEqual('ngShow');

        expect(codeName.getLinkInfo(someDoc, 'input[checkbox]').anchorElement).toEqual('input[checkbox]');
        expect(codeName.getLinkInfo(someDoc, 'filter:currency').anchorElement).toEqual('currency');
        expect(codeName.getLinkInfo(someDoc, 'module:ng.$compile').anchorElement).toEqual('$compile');
      });

      it("should replace references to modules with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'module:ng').anchorElement).toEqual('ng');
        expect(codeName.getLinkInfo(someDoc, 'module:ngRoute').anchorElement).toEqual('ngRoute');
        expect(codeName.getLinkInfo(someDoc, 'module:ngSanitize').anchorElement).toEqual('ngSanitize');
      });

      it("should replace references to code in other modules with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'module:ngRoute.directive:ngView').anchorElement).toEqual('ngView');
      });

      it("should replace references to code in the global namespace with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'global:angular.element').anchorElement).toEqual('angular.element');
        expect(codeName.getLinkInfo(someDoc, 'module:ngMock.global:angular.mock.dump').anchorElement).toEqual('angular.mock.dump');
      });

      it("should replace code references to members of objects with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'module:ng.$location#methods_search', 'search()').anchorElement).toEqual('search()');
      });
    });

  });

  xdescribe("fromPath", function() {
    it("returns a codeName for a given path", function() {
      codeName.apiSection = 'api';
      expect(codeName.fromPath('api/ng/directive/ngClass').toEqual('module:ng.directive:ngClass'));
    });
  });
});<commit_msg>fix(code-name): fix test<commit_after>var codeName = require('../../lib/utils/code-name');

describe("code-name", function() {
  describe("getAbsoluteCodeName", function() {
    it("returns an absolute name given a doc and name in the same module and componentType", function() {
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'ngClass'))
        .toEqual('module:ng.directive:ngClass');

      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');

      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'module:ng.directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');
    });

    it("returns an absolute name given a doc and name in the same module but different componentType", function() {
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');

      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'module:ng.directive:ngClass'))
        .toEqual('module:ng.directive:ngClass');
    });

    it("returns an absolute name given a doc and name in a different module", function() {
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'module:ngRoute.directive:ngView'))
        .toEqual('module:ngRoute.directive:ngView');
      expect(codeName.getAbsoluteCodeName({ module: 'ng', componentType: 'filter', name: 'currency'}, 'module:ngRoute.$route'))
        .toEqual('module:ngRoute.$route');
    });
  });

  xdescribe("relativeName", function() {
    it("returns an relative name given a doc and an absolute name", function() {
      expect(codeName.relativeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'module:ng.directive:ngClass'))
        .toEqual('ngClass');

      expect(codeName.relativeName({ module: 'ng', componentType: 'directive', name: 'ngShow'}, 'module:ng.filter:currency'))
        .toEqual('filter:currency');
    });
  });

  describe("getLinkInfo", function() {
    describe('for real urls', function() {
      it("should replace urls containing slashes with HTML anchors to the same url", function() {
        var someDoc = { };

        expect(codeName.getLinkInfo(someDoc, '/some/absolute/url')).toEqual({ doc: someDoc, url: "/some/absolute/url", title: "url", type: 'url', anchorElement : 'url'});
        expect(codeName.getLinkInfo(someDoc, 'some/relative/url')).toEqual({ doc: someDoc, url: "some/relative/url", title: "url", type: 'url', anchorElement : 'url'});
        expect(codeName.getLinkInfo(someDoc, '../some/other/relative/url')).toEqual({ doc: someDoc, url: "../some/other/relative/url", title: "url", type: 'url', anchorElement : 'url'});
        expect(codeName.getLinkInfo(someDoc, 'http://www.google.com')).toEqual({ doc: someDoc, url: "http://www.google.com", title: "www.google.com", type: 'url', anchorElement : 'www.google.com'});

        expect(codeName.getLinkInfo(someDoc, '/some/absolute/url', 'some link')).toEqual({ doc: someDoc, url: "/some/absolute/url", title: "some link", type: 'url', anchorElement : 'some link'});
        expect(codeName.getLinkInfo(someDoc, 'some/relative/url', 'some other link')).toEqual({ doc: someDoc, url: "some/relative/url", title: "some other link", type: 'url', anchorElement : 'some other link'});
        expect(codeName.getLinkInfo(someDoc, '../some/other/relative/url', 'some link')).toEqual({ doc: someDoc, url: "../some/other/relative/url", title: "some link", type: 'url', anchorElement : 'some link'});
        expect(codeName.getLinkInfo(someDoc, 'http://www.google.com', 'Google')).toEqual({ doc: someDoc, url: "http://www.google.com", title: "Google", type: 'url', anchorElement : 'Google'});
      });
    });

    describe("for code references", function() {
      var someDoc;

      beforeEach(function() {
        someDoc = { module: 'ng', name:'ngClass', componentType:'directive', section: 'api' };
      });

      it("should replace relative references to code in the current module with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'ngShow').anchorElement).toEqual('ngShow');
        expect(codeName.getLinkInfo(someDoc, 'directive:ngShow').anchorElement).toEqual('ngShow');

        expect(codeName.getLinkInfo(someDoc, 'input[checkbox]').anchorElement).toEqual('input[checkbox]');
        expect(codeName.getLinkInfo(someDoc, 'filter:currency').anchorElement).toEqual('currency');
        expect(codeName.getLinkInfo(someDoc, 'module:ng.$compile').anchorElement).toEqual('$compile');
      });

      it("should replace references to modules with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'module:ng').anchorElement).toEqual('ng');
        expect(codeName.getLinkInfo(someDoc, 'module:ngRoute').anchorElement).toEqual('ngRoute');
        expect(codeName.getLinkInfo(someDoc, 'module:ngSanitize').anchorElement).toEqual('ngSanitize');
      });

      it("should replace references to code in other modules with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'module:ngRoute.directive:ngView').anchorElement).toEqual('ngView');
      });

      it("should replace references to code in the global namespace with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'global:angular.element').anchorElement).toEqual('angular.element');
        expect(codeName.getLinkInfo(someDoc, 'module:ngMock.global:angular.mock.dump').anchorElement).toEqual('angular.mock.dump');
      });

      it("should replace code references to members of objects with HTML anchors to the correct url", function() {
        expect(codeName.getLinkInfo(someDoc, 'module:ng.$location#methods_search', 'search()').anchorElement).toEqual('search()');
      });
    });

  });

  xdescribe("fromPath", function() {
    it("returns a codeName for a given path", function() {
      codeName.apiSection = 'api';
      expect(codeName.fromPath('api/ng/directive/ngClass').toEqual('module:ng.directive:ngClass'));
    });
  });
});<|endoftext|>


<commit_before>import {SObject, curryAll} from 'static-land'

function isDigit(x) {
  return x.charCodeAt(0) >= '0'.charCodeAt(0) && x.charCodeAt(0) <= '9'.charCodeAt(0)
}

const Span = curryAll({
  of(time) {
    return {type: 'span', time}
  },
  map(f, span) {
    return Span.of(f(span.time))
  },
  isInstance(span) {
    return span.type === 'span'
  },
  isNotEmpty(span) {
    return span.time !== 0
  },
  sum(a, b) {
    return Span.of(a.time + b.time)
  },
  toString(span) {
    // this is intentionally returns one less symbol
    return Array(span.time).join('_')
  },
})

const Value = curryAll({
  of(value) {
    return {type: 'value', value}
  },
  isInstance(value) {
    return value.type === 'value'
  },
  toString(value) {
    const type = typeof value.value
    if ((type === 'string' || type === 'number') && String(value.value).length === 1) {
      return String(value.value)
    }
    return `(${JSON.stringify(value.value)})`
  },
})

const Marbles = curryAll({
  skipSpan(time, marbles) {
    return Marbles.mapHeadSpan(t => t - time, marbles)
  },
  mapHeadSpan(f, marbles) {
    const span = Span.map(f, marbles[0])
    const rest = marbles.slice(1)
    return Span.isNotEmpty(span) ? [span].concat(rest) : rest
  },
  popHeadValue(f, marbles) {
    f(marbles[0].value)
    return marbles.slice(1)
  },
  isNotEmpty(marbles) {
    return marbles.length !== 0
  },
  isHeadValue(marbles) {
    return Value.isInstance(marbles[0])
  },
  getHeadTime(marbles) {
    return marbles[0].time
  },
  squashSpans(marbles) {
    return marbles.reduce((acc, x) => {
      const last = acc[acc.length - 1]
      if (last && Span.isInstance(last) && Span.isInstance(x)) {
        return acc.slice(0, acc.length - 1).concat([Span.sum(last, x)])
      }
      return acc.concat([x])
    }, [])
  },
  toString(marbles) {
    return marbles.map(x => Value.isInstance(x) ? Value.toString(x) : Span.toString(x)).join('')
  },
  fromString(str) {
    // {stuff} not supported
    return Marbles.squashSpans(str.split('').map(
      x => x === '_' ? [span(1)] : [span(1), value(isDigit(x) ? Number(x) : x)]
    ).reduce((a, b) => a.concat(b), []))
  },
})

const QueueItem = curryAll({
  map(f, item) {
    return {sink: item.sink, marbles: f(item.marbles)}
  },
  skipSpan(time, item) {
    return QueueItem.map(Marbles.skipSpan(time), item)
  },
  applyValue(item) {
    return QueueItem.map(Marbles.popHeadValue(item.sink), item)
  },
  isNotEmpty(item) {
    return Marbles.isNotEmpty(item.marbles)
  },
  isHeadValue(item) {
    return Marbles.isHeadValue(item.marbles)
  },
  getHeadTime(item) {
    return Marbles.getHeadTime(item.marbles)
  },
})

const Queue = curryAll({
  map(f, queue) {
    return Queue.cleanup(queue.map(f))
  },
  mapItem(f, item, queue) {
    return Queue.map(i => i === item ? f(i) : i, queue)
  },
  cleanup(queue) {
    return queue.filter(QueueItem.isNotEmpty)
  },
  execNext(onSpanSkip, queue) {
    let smallestSpan = Infinity
    for (let item of queue) {
      if (QueueItem.isHeadValue(item)) {
        return Queue.mapItem(QueueItem.applyValue, item, queue)
      } else {
        smallestSpan = Math.min(QueueItem.getHeadTime(item), smallestSpan)
      }
    }
    onSpanSkip(smallestSpan)
    return Queue.map(QueueItem.skipSpan(smallestSpan), queue)
  },
  isNotEmpty(queue) {
    return queue.length !== 0
  },
  push(item, queue) {
    return queue.concat([item])
  },
  removeBySink(sink, queue) {
    return queue.filter(i => i.sink !== sink)
  },
})

export function span(time) {
  return Span.of(time)
}

export function value(value) {
  return Value.of(value)
}

export function fromString(str) {
  return Marbles.fromString(str)
}

export function toString(marbles) {
  return Marbles.toString(marbles)
}

export function exec(sourcesSpec, transformer) {

  let queue = []
  let inUpdate = false
  const plannedUpdates = []
  function updateQueue(f) {
    plannedUpdates.push(f)
    if (inUpdate) {
      return
    }
    inUpdate = true
    while(plannedUpdates.length > 0) {
      queue = plannedUpdates.shift()(queue)
    }
    inUpdate = false
  }

  const sources = SObject.map(marbles => {
    return sink => {
      updateQueue(Queue.push({sink, marbles}))
      return () => {updateQueue(Queue.removeBySink(sink))}
    }
  }, sourcesSpec)

  const result = []
  function toResult(type) {
    return x => {result.push(type(x))}
  }

  const targetStream = transformer(sources)
  const disposeTarget = targetStream(toResult(value))

  while (Queue.isNotEmpty(queue)) {
    updateQueue(Queue.execNext(toResult(span)))
  }

  disposeTarget()
  return Marbles.squashSpans(result)
}
<commit_msg>a todo comment<commit_after>import {SObject, curryAll} from 'static-land'

function isDigit(x) {
  return x.charCodeAt(0) >= '0'.charCodeAt(0) && x.charCodeAt(0) <= '9'.charCodeAt(0)
}

const Span = curryAll({
  of(time) {
    return {type: 'span', time}
  },
  map(f, span) {
    return Span.of(f(span.time))
  },
  isInstance(span) {
    return span.type === 'span'
  },
  isNotEmpty(span) {
    return span.time !== 0
  },
  sum(a, b) {
    return Span.of(a.time + b.time)
  },
  toString(span) {
    // this is intentionally returns one less symbol
    return Array(span.time).join('_')
  },
})

const Value = curryAll({
  of(value) {
    return {type: 'value', value}
  },
  isInstance(value) {
    return value.type === 'value'
  },
  toString(value) {
    const type = typeof value.value
    if ((type === 'string' || type === 'number') && String(value.value).length === 1) {
      return String(value.value)
    }
    return `(${JSON.stringify(value.value)})`
  },
})

const Marbles = curryAll({
  skipSpan(time, marbles) {
    return Marbles.mapHeadSpan(t => t - time, marbles)
  },
  mapHeadSpan(f, marbles) {
    const span = Span.map(f, marbles[0])
    const rest = marbles.slice(1)
    return Span.isNotEmpty(span) ? [span].concat(rest) : rest
  },
  popHeadValue(f, marbles) {
    f(marbles[0].value)
    return marbles.slice(1)
  },
  isNotEmpty(marbles) {
    return marbles.length !== 0
  },
  isHeadValue(marbles) {
    return Value.isInstance(marbles[0])
  },
  getHeadTime(marbles) {
    return marbles[0].time
  },
  squashSpans(marbles) {
    return marbles.reduce((acc, x) => {
      const last = acc[acc.length - 1]
      if (last && Span.isInstance(last) && Span.isInstance(x)) {
        return acc.slice(0, acc.length - 1).concat([Span.sum(last, x)])
      }
      return acc.concat([x])
    }, [])
  },
  toString(marbles) {
    return marbles.map(x => Value.isInstance(x) ? Value.toString(x) : Span.toString(x)).join('')
  },
  fromString(str) {
    // {stuff} not supported
    return Marbles.squashSpans(str.split('').map(
      x => x === '_' ? [span(1)] : [span(1), value(isDigit(x) ? Number(x) : x)]
    ).reduce((a, b) => a.concat(b), []))
  },
})

const QueueItem = curryAll({
  map(f, item) {
    return {sink: item.sink, marbles: f(item.marbles)}
  },
  skipSpan(time, item) {
    return QueueItem.map(Marbles.skipSpan(time), item)
  },
  applyValue(item) {
    return QueueItem.map(Marbles.popHeadValue(item.sink), item)
  },
  isNotEmpty(item) {
    return Marbles.isNotEmpty(item.marbles)
  },
  isHeadValue(item) {
    return Marbles.isHeadValue(item.marbles)
  },
  getHeadTime(item) {
    return Marbles.getHeadTime(item.marbles)
  },
})

const Queue = curryAll({
  map(f, queue) {
    return Queue.cleanup(queue.map(f))
  },
  mapItem(f, item, queue) {
    return Queue.map(i => i === item ? f(i) : i, queue)
  },
  cleanup(queue) {
    return queue.filter(QueueItem.isNotEmpty)
  },
  execNext(onSpanSkip, queue) {
    let smallestSpan = Infinity
    for (let item of queue) {
      if (QueueItem.isHeadValue(item)) {
        return Queue.mapItem(QueueItem.applyValue, item, queue)
      } else {
        smallestSpan = Math.min(QueueItem.getHeadTime(item), smallestSpan)
      }
    }
    onSpanSkip(smallestSpan)
    return Queue.map(QueueItem.skipSpan(smallestSpan), queue)
  },
  isNotEmpty(queue) {
    return queue.length !== 0
  },
  push(item, queue) {
    return queue.concat([item])
  },
  removeBySink(sink, queue) {
    return queue.filter(i => i.sink !== sink)
  },
})

export function span(time) {
  return Span.of(time)
}

export function value(value) {
  return Value.of(value)
}

export function fromString(str) {
  return Marbles.fromString(str)
}

export function toString(marbles) {
  return Marbles.toString(marbles)
}

export function exec(sourcesSpec, transformer) {

  let queue = []
  let inUpdate = false
  const plannedUpdates = []
  function updateQueue(f) {
    plannedUpdates.push(f)
    if (inUpdate) {
      return
    }
    inUpdate = true
    while(plannedUpdates.length > 0) {
      queue = plannedUpdates.shift()(queue)
    }
    inUpdate = false
  }

  const sources = SObject.map(marbles => {
    return sink => {
      updateQueue(Queue.push({sink, marbles}))
      return () => {updateQueue(Queue.removeBySink(sink))}
    }
  }, sourcesSpec)

  const result = []
  function toResult(type) {
    return x => {result.push(type(x))}
  }

  const targetStream = transformer(sources)
  const disposeTarget = targetStream(toResult(value))

  while (Queue.isNotEmpty(queue)) {
    updateQueue(Queue.execNext(toResult(span)))
  }

  disposeTarget()
  return Marbles.squashSpans(result)
}

/* TODO

renderMany({
  a: fromString(...),
  b: fromString(...),
  c: fromString(...),
})

a: _ _1___
b: _1_ ___

& add `+ 1` in Span.toString

*/
<|endoftext|>


<commit_before>/* @flow */

export default function memoize<Result, Deps: any[]>(
  callback: (...deps: Deps) => Result
) {
  let previous: ?Deps;
  let result: ?Result;

  return (...dependencies: Deps) => {
    let hasChanged = false;

    if (previous) {
      if (previous.length !== dependencies.length) {
        hasChanged = true;
      } else {
        for (let i = 0; i < previous.length; i++) {
          if (previous[i] !== dependencies[i]) {
            hasChanged = true;
            break;
          }
        }
      }
    } else {
      hasChanged = true;
    }

    previous = dependencies;

    if (hasChanged || result === undefined) {
      result = callback(...dependencies);
    }

    return result;
  };
}
<commit_msg>refactor: tweak flow types for memoize<commit_after>/* @flow */

export default function memoize<Result, Deps: $ReadOnlyArray<any>>(
  callback: (...deps: Deps) => Result
) {
  let previous: ?Deps;
  let result: ?Result;

  return (...dependencies: Deps): Result => {
    let hasChanged = false;

    if (previous) {
      if (previous.length !== dependencies.length) {
        hasChanged = true;
      } else {
        for (let i = 0; i < previous.length; i++) {
          if (previous[i] !== dependencies[i]) {
            hasChanged = true;
            break;
          }
        }
      }
    } else {
      hasChanged = true;
    }

    previous = dependencies;

    if (hasChanged || result === undefined) {
      result = callback(...dependencies);
    }

    /* $FlowFixMe: we initialize result if it's undefined above */
    return result;
  };
}
<|endoftext|>


<commit_before>import {
  isArray,
  isString,
  isUndefined,
} from './common/utils'

import Helper, { typeTag, prepareAddress } from './common/helpers'

import AtomicBlob from './atomic/blob'
import AtomicFloat32 from './atomic/float32'
import AtomicFloat64 from './atomic/float64'
import AtomicInt32 from './atomic/int32'
import AtomicInt64 from './atomic/int64'
import AtomicUInt64 from './atomic/uint64'
import AtomicString from './atomic/string'

/**
 * TypedMessage is the superclass of Message. It can be used to compose an OSC
 * message with explicit data types.
 */
export class TypedMessage {
  /**
   * Create a TypedMessage instance
   * @param {array|string} args Address
   *
   * @example
   * const message = new TypedMessage(['test', 'path'])
   * message.add('d', 123.123456789)
   * message.add('s', 'hello')
   *
   * @example
   * const message = new Message('/test/path')
   */
  constructor(address) {
    /**
     * @type {number} offset
     * @private
     */
    this.offset = 0
    /** @type {string} address */
    this.address = ''
    /** @type {string} types */
    this.types = ''
    /** @type {array} args */
    this.args = []

    if (!isUndefined(address)) {
      if (!(isString(address) || isArray(address))) {
        throw new Error('OSC Message constructor first argument (address) must be a string or array')
      }

      this.address = prepareAddress(address)
    }
  }

  /**
   * Add an OSC Atomic Data Type to the list of elements
   * @param {string} type
   * @param {*} item
   */
  add(type, item) {
    if (isUndefined(type)) {
      throw new Error('OSC Message needs a valid OSC Atomic Data Type')
    }

    // Some data types e.g. boolean does not require item
    if (!isUndefined(item)) {
      this.args.push(item)
    }

    this.types += type
  }

  /**
   * Interpret the Message as packed binary data
   * @return {Uint8Array} Packed binary data
   */
  pack() {
    if (this.address.length === 0 || this.address[0] !== '/') {
      throw new Error('OSC Message has an invalid address')
    }

    const encoder = new Helper()

    // OSC Address Pattern and Type string
    encoder.add(new AtomicString(this.address))
    encoder.add(new AtomicString(`,${this.types}`))

    // followed by zero or more OSC Arguments
    if (this.types.length > 0) {
      let argument
      let index = 0
      for (let i = 0; i < this.types.length; i += 1) {
        const type = this.types[i]
        const value = this.args[index]

        if (type === 'i') {
          argument = new AtomicInt32(value)
          index += 1
        } else if (type === 'h') {
          argument = new AtomicInt64(value)
          index += 1
        } else if (type === 't') {
          argument = new AtomicUInt64(value)
          index += 1
        } else if (type === 'f') {
          argument = new AtomicFloat32(value)
          index += 1
        } else if (type === 'd') {
          argument = new AtomicFloat64(value)
          index += 1
        } else if (type === 's') {
          argument = new AtomicString(value)
          index += 1
        } else if (type === 'b') {
          argument = new AtomicBlob(value)
          index += 1
        } else if (type === 'T' || type === 'F') {
          argument = null
        } else if (type === 'N') {
          argument = null
        } else if (type === 'I') {
          argument = null
        } else {
          throw new Error('OSC Message found unknown argument type')
        }

        if (argument !== null) {
          encoder.add(argument)
        }
      }
    }

    return encoder.merge()
  }

  /**
   * Unpack binary data to read a Message
   * @param {DataView} dataView The DataView holding the binary representation of a Message
   * @param {number} [initialOffset=0] Offset of DataView before unpacking
   * @return {number} Offset after unpacking
   */
  unpack(dataView, initialOffset = 0) {
    if (!(dataView instanceof DataView)) {
      throw new Error('OSC Message expects an instance of type DataView.')
    }

    // read address pattern
    const address = new AtomicString()
    address.unpack(dataView, initialOffset)

    // read type string
    const types = new AtomicString()
    types.unpack(dataView, address.offset)

    if (address.value.length === 0 || address.value[0] !== '/') {
      throw new Error('OSC Message found malformed or missing address string')
    }

    if (types.value.length === 0 && types.value[0] !== ',') {
      throw new Error('OSC Message found malformed or missing type string')
    }

    let { offset } = types
    let next
    let type

    const args = []

    // read message arguments (OSC Atomic Data Types)
    for (let i = 1; i < types.value.length; i += 1) {
      type = types.value[i]

      if (type === 'i') {
        next = new AtomicInt32()
      } else if (type === 'h') {
        next = new AtomicInt64()
      } else if (type === 't') {
        next = new AtomicUInt64()
      } else if (type === 'f') {
        next = new AtomicFloat32()
      } else if (type === 'd') {
        next = new AtomicFloat64()
      } else if (type === 's') {
        next = new AtomicString()
      } else if (type === 'b') {
        next = new AtomicBlob()
      } else if (type === 'T' || type === 'F') {
        next = null
      } else if (type === 'N') {
        next = null
      } else if (type === 'I') {
        next = null
      } else {
        throw new Error('OSC Message found non-standard argument type')
      }

      if (next !== null) {
        offset = next.unpack(dataView, offset)
        args.push(next.value)
      }
    }

    this.offset = offset
    this.address = address.value
    this.types = types.value
    this.args = args

    return this.offset
  }
}

/**
 * An OSC message consists of an OSC Address Pattern followed
 * by an OSC Type Tag String followed by zero or more OSC Arguments
 */
export default class Message extends TypedMessage {
  /**
   * Create a Message instance
   * @param {array|string} args Address
   * @param {...*} args OSC Atomic Data Types
   *
   * @example
   * const message = new Message(['test', 'path'], 50, 100.52, 'test')
   *
   * @example
   * const message = new Message('/test/path', 51.2)
   */
  constructor(...args) {
    let address
    if (args.length > 0) {
      address = args.shift()
    }

    super(address)

    if (args.length > 0) {
      this.types = args.map((item) => typeTag(item)).join('')
      this.args = args
    }
  }

  /**
   * Add an OSC Atomic Data Type to the list of elements
   * @param {*} item
   */
  add(item) {
    super.add(typeTag(item), item)
  }
}
<commit_msg>Iterate over args instead of types in pack()<commit_after>import {
  isArray,
  isString,
  isUndefined,
} from './common/utils'

import Helper, { typeTag, prepareAddress } from './common/helpers'

import AtomicBlob from './atomic/blob'
import AtomicFloat32 from './atomic/float32'
import AtomicFloat64 from './atomic/float64'
import AtomicInt32 from './atomic/int32'
import AtomicInt64 from './atomic/int64'
import AtomicUInt64 from './atomic/uint64'
import AtomicString from './atomic/string'

/**
 * TypedMessage is the superclass of Message. It can be used to compose an OSC
 * message with explicit data types.
 */
export class TypedMessage {
  /**
   * Create a TypedMessage instance
   * @param {array|string} args Address
   *
   * @example
   * const message = new TypedMessage(['test', 'path'])
   * message.add('d', 123.123456789)
   * message.add('s', 'hello')
   *
   * @example
   * const message = new Message('/test/path')
   */
  constructor(address) {
    /**
     * @type {number} offset
     * @private
     */
    this.offset = 0
    /** @type {string} address */
    this.address = ''
    /** @type {string} types */
    this.types = ''
    /** @type {array} args */
    this.args = []

    if (!isUndefined(address)) {
      if (!(isString(address) || isArray(address))) {
        throw new Error('OSC Message constructor first argument (address) must be a string or array')
      }

      this.address = prepareAddress(address)
    }
  }

  /**
   * Add an OSC Atomic Data Type to the list of elements
   * @param {string} type
   * @param {*} item
   */
  add(type, item) {
    if (isUndefined(type)) {
      throw new Error('OSC Message needs a valid OSC Atomic Data Type')
    }

    // Some data types e.g. boolean does not require item
    if (!isUndefined(item)) {
      this.args.push(item)
    }

    this.types += type
  }

  /**
   * Interpret the Message as packed binary data
   * @return {Uint8Array} Packed binary data
   */
  pack() {
    if (this.address.length === 0 || this.address[0] !== '/') {
      throw new Error('OSC Message has an invalid address')
    }

    const encoder = new Helper()

    // OSC Address Pattern and Type string
    encoder.add(new AtomicString(this.address))
    encoder.add(new AtomicString(`,${this.types}`))

    // followed by zero or more OSC Arguments
    if (this.args.length > 0) {
      let argument

      if (this.args.length > this.types.length) {
        throw new Error('OSC Message argument and type tag mismatch')
      }

      this.args.forEach((value, index) => {
        const type = this.types[index]
        if (type === 'i') {
          argument = new AtomicInt32(value)
        } else if (type === 'h') {
          argument = new AtomicInt64(value)
        } else if (type === 't') {
          argument = new AtomicUInt64(value)
        } else if (type === 'f') {
          argument = new AtomicFloat32(value)
        } else if (type === 'd') {
          argument = new AtomicFloat64(value)
        } else if (type === 's') {
          argument = new AtomicString(value)
        } else if (type === 'b') {
          argument = new AtomicBlob(value)
        } else {
          throw new Error('OSC Message found unknown argument type')
        }

        encoder.add(argument)
      })
    }

    return encoder.merge()
  }

  /**
   * Unpack binary data to read a Message
   * @param {DataView} dataView The DataView holding the binary representation of a Message
   * @param {number} [initialOffset=0] Offset of DataView before unpacking
   * @return {number} Offset after unpacking
   */
  unpack(dataView, initialOffset = 0) {
    if (!(dataView instanceof DataView)) {
      throw new Error('OSC Message expects an instance of type DataView.')
    }

    // read address pattern
    const address = new AtomicString()
    address.unpack(dataView, initialOffset)

    // read type string
    const types = new AtomicString()
    types.unpack(dataView, address.offset)

    if (address.value.length === 0 || address.value[0] !== '/') {
      throw new Error('OSC Message found malformed or missing address string')
    }

    if (types.value.length === 0 && types.value[0] !== ',') {
      throw new Error('OSC Message found malformed or missing type string')
    }

    let { offset } = types
    let next
    let type

    const args = []

    // read message arguments (OSC Atomic Data Types)
    for (let i = 1; i < types.value.length; i += 1) {
      type = types.value[i]

      if (type === 'i') {
        next = new AtomicInt32()
      } else if (type === 'h') {
        next = new AtomicInt64()
      } else if (type === 't') {
        next = new AtomicUInt64()
      } else if (type === 'f') {
        next = new AtomicFloat32()
      } else if (type === 'd') {
        next = new AtomicFloat64()
      } else if (type === 's') {
        next = new AtomicString()
      } else if (type === 'b') {
        next = new AtomicBlob()
      } else if (type === 'T' || type === 'F') {
        next = null
      } else if (type === 'N') {
        next = null
      } else if (type === 'I') {
        next = null
      } else {
        throw new Error('OSC Message found non-standard argument type')
      }

      if (next !== null) {
        offset = next.unpack(dataView, offset)
        args.push(next.value)
      }
    }

    this.offset = offset
    this.address = address.value
    this.types = types.value
    this.args = args

    return this.offset
  }
}

/**
 * An OSC message consists of an OSC Address Pattern followed
 * by an OSC Type Tag String followed by zero or more OSC Arguments
 */
export default class Message extends TypedMessage {
  /**
   * Create a Message instance
   * @param {array|string} args Address
   * @param {...*} args OSC Atomic Data Types
   *
   * @example
   * const message = new Message(['test', 'path'], 50, 100.52, 'test')
   *
   * @example
   * const message = new Message('/test/path', 51.2)
   */
  constructor(...args) {
    let address
    if (args.length > 0) {
      address = args.shift()
    }

    super(address)

    if (args.length > 0) {
      this.types = args.map((item) => typeTag(item)).join('')
      this.args = args
    }
  }

  /**
   * Add an OSC Atomic Data Type to the list of elements
   * @param {*} item
   */
  add(item) {
    super.add(typeTag(item), item)
  }
}
<|endoftext|>


<commit_before>'use strict';

class Minutes {

    constructor(minutes, opts) {

        // Atempt to parse the minutes as an integer.
        this.minutes = parseInt(minutes);

        // Only accept an integer.
        if (Number.isNaN()) {
            throw new Error('Minutes accepts an integer representing minutes.');
        }

        // Accept some options, default those that don't exist.
        this.opts = opts || {};

        // Default the time units.
        this.opts.units = this.opts.units || {};
        this.opts.units.w = this.opts.units.w || 'week';
        this.opts.units.d = this.opts.units.d || 'day';
        this.opts.units.h = this.opts.units.h || 'hour';
        this.opts.units.m = this.opts.units.m || 'minute';

        // Default pluralize (to true).
        this.opts.pluralize = (typeof this.opts.pluralize === 'undefined') ? true : this.opts.pluralize;

        // Default separation tokens.
        this.opts.tokens = this.opts.tokens || {};
        this.opts.tokens.space = (typeof this.opts.tokens.space === 'undefined') ? ' ' : this.opts.tokens.space;
        this.opts.tokens.comma = (typeof this.opts.tokens.comma === 'undefined') ? ', ' : this.opts.tokens.comma;
        this.opts.tokens.and = (typeof this.opts.tokens.and === 'undefined') ? ' and ' : this.opts.tokens.and;
        this.opts.tokens.plural = (typeof this.opts.tokens.plural === 'undefined') ? 's' : this.opts.tokens.plural;

    }

    toString () {

        // The delta will reduce in scope as we move through the various time units.
        // Each time a time unit is matched, remove that unit from the delta.
        var delta = this.minutes,
            parts = [];

        // Determine the time period.

        // Are the minutes greater than a week?
        if (delta >= Minutes.week()) {
            parts.push(this.formatPart(Math.floor(delta/Minutes.week()), 'w'));
            delta -= Math.floor(delta/Minutes.week())*Minutes.week();
        }

        // Are the remaining(?) minutes greater than a day?
        if (delta >= Minutes.day()) {
            parts.push(this.formatPart(Math.floor(delta/Minutes.day()), 'd'));
            delta -= Math.floor(delta/Minutes.day())*Minutes.day();
        }

        // Are the remaining(?) minutes greather than an hour?
        if (delta >= Minutes.hour()) {
            parts.push(this.formatPart(Math.floor(delta/Minutes.hour()), 'h'));
            delta -= Math.floor(delta/Minutes.hour())*Minutes.hour();
        }

        // Are there any remaining minutes?
        if (delta > 0 && delta < Minutes.hour()) {
            parts.push(this.formatPart(delta, 'm'));
        }

        // Create the regex to replace the last occurance of `this.opts.tokens.comma` with `this.opts.tokens.and`.
        var lastOccurence = new RegExp(Minutes.safeRegExpString(this.opts.tokens.comma) + '(?!.*' + Minutes.safeRegExpString(this.opts.tokens.comma) + ')');

        // Join parts with `,`, other than the final one which should be `and`.
        return parts.join(this.opts.tokens.comma).replace(lastOccurence, this.opts.tokens.and);

    }

    //
    // Instance methods.
    //

    /*
     * Format a time unit (i.e. 1 h as '1 hour').
     * @return {String}
    */
    formatPart (value, unit) {

        var str = value + this.opts.tokens.space + this.opts.units[unit];

        // Make the unit representation plural if required.
        if (this.opts.pluralize && value > 1) {
            str += this.opts.tokens.plural;
        }

        return str;

    }

    //
    // Static methods.
    //

    /*
     * Return the number of minutes in an hour.
     * @return {Number}
    */
    static hour () {
        return 60;
    }

    /*
     * Return the number of minutes in a day.
     * @return {Number}
    */
    static day () {
        return 24*Minutes.hour();
    }

    /*
     * Return the number of minutes in a week.
     * @return {Number}
    */
    static week () {
        return 7*Minutes.day();
    }

    /*
     * Return a string that is safe to be used when dynamically building a regular expression.
     * @return {Number}
    */
    static safeRegExpString (str) {

        str = str.replace(/(?:\.|\^|\$|\&|\`|\*|\(|\)|\||\?|\:|\=)/g, '\\$&');

        return str;

    }

}

module.exports = Minutes;
<commit_msg>Improved in-code comments.<commit_after>'use strict';

class Minutes {

    /**
     * Create a new instance of minutes, scoped to an integer passed in.
     * @param  {Number} minutes The number of minutes this instance should work with.
     * @param  {Object} opts    The options to alter this particular instance of minutes.js
     * @return {Object}         The initialized instance of Minutes.
     */
    constructor(minutes, opts) {

        // Atempt to parse the minutes as an integer.
        this.minutes = parseInt(minutes);

        // Only accept an integer.
        if (Number.isNaN()) {
            throw new Error('Minutes accepts an integer representing minutes.');
        }

        // Accept some options, default those that don't exist.
        this.opts = opts || {};

        // Default the time units.
        this.opts.units = this.opts.units || {};
        this.opts.units.w = this.opts.units.w || 'week';
        this.opts.units.d = this.opts.units.d || 'day';
        this.opts.units.h = this.opts.units.h || 'hour';
        this.opts.units.m = this.opts.units.m || 'minute';

        // Default pluralize (to true).
        this.opts.pluralize = (typeof this.opts.pluralize === 'undefined') ? true : this.opts.pluralize;

        // Default separation tokens.
        this.opts.tokens = this.opts.tokens || {};
        this.opts.tokens.space = (typeof this.opts.tokens.space === 'undefined') ? ' ' : this.opts.tokens.space;
        this.opts.tokens.comma = (typeof this.opts.tokens.comma === 'undefined') ? ', ' : this.opts.tokens.comma;
        this.opts.tokens.and = (typeof this.opts.tokens.and === 'undefined') ? ' and ' : this.opts.tokens.and;
        this.opts.tokens.plural = (typeof this.opts.tokens.plural === 'undefined') ? 's' : this.opts.tokens.plural;

        return this;

    }

    /**
     * Using the options provided to the constructor take the value of the minutes and
     * format into a string.
     * @return {String} The formatted string (i.e. `10630` becomes `7 days, 9 hours and 10 minutes`).
     */
    toString () {

        // The delta will reduce in scope as we move through the various time units.
        // Each time a time unit is matched, remove that unit from the delta.
        var delta = this.minutes,
            parts = [];

        // Determine the time period.

        // Are the minutes greater than a week?
        if (delta >= Minutes.week()) {
            parts.push(this.formatPart(Math.floor(delta/Minutes.week()), 'w'));
            delta -= Math.floor(delta/Minutes.week())*Minutes.week();
        }

        // Are the remaining(?) minutes greater than a day?
        if (delta >= Minutes.day()) {
            parts.push(this.formatPart(Math.floor(delta/Minutes.day()), 'd'));
            delta -= Math.floor(delta/Minutes.day())*Minutes.day();
        }

        // Are the remaining(?) minutes greather than an hour?
        if (delta >= Minutes.hour()) {
            parts.push(this.formatPart(Math.floor(delta/Minutes.hour()), 'h'));
            delta -= Math.floor(delta/Minutes.hour())*Minutes.hour();
        }

        // Are there any remaining minutes?
        if (delta > 0 && delta < Minutes.hour()) {
            parts.push(this.formatPart(delta, 'm'));
        }

        // Create the regex to replace the last occurance of `this.opts.tokens.comma` with `this.opts.tokens.and`.
        var lastOccurence = new RegExp(Minutes.safeRegExpString(this.opts.tokens.comma) + '(?!.*' + Minutes.safeRegExpString(this.opts.tokens.comma) + ')');

        // Join parts with `,`, other than the final one which should be `and`.
        return parts.join(this.opts.tokens.comma).replace(lastOccurence, this.opts.tokens.and);

    }

    //
    // Instance methods.
    //

    /**
     * Format a time unit (i.e. 1 h as '1 hour').
     * @param  {Number} value The value of the time unit.
     * @param  {String} unit  The time unit (either `'w'`, `'h'`, `'m'`, `'d'`).
     * @return {String}       The string representation of the time unit (i.e. 5 hours).
     */
    formatPart (value, unit) {

        var str = value + this.opts.tokens.space + this.opts.units[unit];

        // Make the unit representation plural if required.
        if (this.opts.pluralize && value > 1) {
            str += this.opts.tokens.plural;
        }

        return str;

    }

    //
    // Static methods.
    //

    /**
     * Return the number of minutes in an hour.
     * @return {Number} 60
     */
    static hour () {
        return 60;
    }

    /**
     * Return the number of minutes in a day.
     * @return {Number} 1440
     */
    static day () {
        return 24*Minutes.hour();
    }

    /**
     * Return the number of minutes in a week.
     * @return {Number} 10080.
     */
    static week () {
        return 7*Minutes.day();
    }

    /**
     * Return a string that is safe to be used when dynamically building a regular expression.
     * @param  {String} str The string to escaped.
     * @return {String}     An escaped version of `str`.
     */
    static safeRegExpString (str) {

        str = str.replace(/(?:\.|\^|\$|\&|\`|\*|\(|\)|\||\?|\:|\=)/g, '\\$&');

        return str;

    }

}

module.exports = Minutes;
<|endoftext|>


<commit_before>import {Component, createElement} from 'react';
import Rx from 'rxjs';

const actionFlow = new Rx.Subject();
const flow = actionFlow.scan(({state}, update) => {
        let change = update instanceof Function ? update(state) : update;
        return {update: change, state: Object.assign(state, change)};
    }
    , {state: {}})
    .filter(({update}) => update instanceof Object && Object.keys(update).length)
    .publishBehavior({update: {}, state: {}});

flow.connect();

const connect = (WrappedComponent, stateInjector = true, actionInjector) => {
    let actionHandlers = {};
    for (let key in actionInjector) {
        actionHandlers[key] = (...params) => actionFlow.next(actionInjector[key](...params));
    }
    let nameMapping = [];
    let funcMapping = [];
    if (stateInjector instanceof Object && Object.keys(stateInjector).length) {
        for (let key in stateInjector) {
            if (stateInjector[key] === true) {
                nameMapping.push(key)
            }
            else if (stateInjector[key] instanceof Function) {
                funcMapping.push(key)
            }
        }
    }
    class Connect extends Component {
        componentWillMount() {
            if (funcMapping.length) {
                this.subscription = flow
                    .map(({state}) => {
                        let impact = {};
                        funcMapping.forEach(key => impact[key] = stateInjector[key](state));
                        nameMapping.forEach(key => impact[key] = state[key]);
                        return impact;
                    })
                    .subscribe(impact => this.setState(impact));
            }
            else if (nameMapping.length) {
                this.subscription = flow
                    .filter(({update}) => {
                        let updateKeys = Object.keys(update);
                        return !!nameMapping.find(prop => updateKeys.includes(prop))
                    })
                    .subscribe(({update}) => this.setState(update));
            }
            else if (stateInjector === true) {
                this.subscription = flow.subscribe(({update}) => this.setState(update));
            }
        }

        componentWillUnmount() {
            if (this.subscription) {
                this.subscription.unsubscribe();
            }
        }

        render() {
            return createElement(WrappedComponent, Object.assign({}, this.state, actionHandlers, this.props));
        }
    }
    return Connect;
}

const next = (state) => actionFlow.next(state);

const initState = (state) => {
    next(currentState => {
        if (currentState) {
            Object.keys(currentState).forEach(key => {
                delete currentState[key]
            });
        }
        return state;
    });
};

const subscribe = (observer) => flow.subscribe(({update, state}) => observer(update, state));

export {connect, next, subscribe, initState};<commit_msg>ConnectedComponent can getWrappedComponent()<commit_after>import {Component, createElement} from 'react';
import Rx from 'rxjs';

const actionFlow = new Rx.Subject();
const flow = actionFlow.scan(({state}, update) => {
        let change = update instanceof Function ? update(state) : update;
        return {update: change, state: Object.assign(state, change)};
    }
    , {state: {}})
    .filter(({update}) => update instanceof Object && Object.keys(update).length)
    .publishBehavior({update: {}, state: {}});

flow.connect();

const connect = (WrappedComponent, stateInjector = true, actionInjector) => {
    let actionHandlers = {};
    for (let key in actionInjector) {
        actionHandlers[key] = (...params) => actionFlow.next(actionInjector[key](...params));
    }
    let nameMapping = [];
    let funcMapping = [];
    if (stateInjector instanceof Object && Object.keys(stateInjector).length) {
        for (let key in stateInjector) {
            if (stateInjector[key] === true) {
                nameMapping.push(key)
            }
            else if (stateInjector[key] instanceof Function) {
                funcMapping.push(key)
            }
        }
    }
    class Connect extends Component {
        componentWillMount() {
            if (funcMapping.length) {
                this.subscription = flow
                    .map(({state}) => {
                        let impact = {};
                        funcMapping.forEach(key => impact[key] = stateInjector[key](state));
                        nameMapping.forEach(key => impact[key] = state[key]);
                        return impact;
                    })
                    .subscribe(impact => this.setState(impact));
            }
            else if (nameMapping.length) {
                this.subscription = flow
                    .filter(({update}) => {
                        let updateKeys = Object.keys(update);
                        return !!nameMapping.find(prop => updateKeys.includes(prop))
                    })
                    .subscribe(({update}) => this.setState(update));
            }
            else if (stateInjector === true) {
                this.subscription = flow.subscribe(({update}) => this.setState(update));
            }
        }

        componentWillUnmount() {
            if (this.subscription) {
                this.subscription.unsubscribe();
            }
        }

        render() {
            return createElement(WrappedComponent, Object.assign({}, this.state, actionHandlers, this.props));
        }

        static getWrappedComponent() {
            return WrappedComponent;
        }
    }
    return Connect;
}

const next = (state) => actionFlow.next(state);

const initState = (state) => {
    next(currentState => {
        if (currentState) {
            Object.keys(currentState).forEach(key => {
                delete currentState[key]
            });
        }
        return state;
    });
};

const subscribe = (observer) => flow.subscribe(({update, state}) => observer(update, state));

export {connect, next, subscribe, initState};<|endoftext|>


<commit_before>// Restores preferences from chrome.storage.
function restoreOptions() {
	chrome.storage.sync.get({
		preserveLastCode: true,
		replaceNewTab: true
	}, function(items) {
		document.forms.optionsForm.preserveLastCode.checked = items.preserveLastCode;
		document.forms.optionsForm.replaceNewTab.checked = items.replaceNewTab;
	});
}

function saveOptions(e) {
	var preserveLastCode = document.forms.optionsForm.preserveLastCode.checked;
	var replaceNewTab = document.forms.optionsForm.replaceNewTab.checked;

	chrome.storage.sync.set({
		preserveLastCode: preserveLastCode,
		replaceNewTab: replaceNewTab
	}, function() {
		var status = document.getElementById('js-status');
		status.textContent = 'Settings saved.';
		setTimeout(function() {
			status.innerHTML = ' ';
		}, 750);
	});

	e.preventDefault();
}

document.addEventListener('DOMContentLoaded', restoreOptions);
document.forms.optionsForm.addEventListener('submit',
	saveOptions);<commit_msg>Change default val of replaceNewTab in options page also<commit_after>// Restores preferences from chrome.storage.
function restoreOptions() {
	chrome.storage.sync.get({
		preserveLastCode: true,
		replaceNewTab: false
	}, function(items) {
		document.forms.optionsForm.preserveLastCode.checked = items.preserveLastCode;
		document.forms.optionsForm.replaceNewTab.checked = items.replaceNewTab;
	});
}

function saveOptions(e) {
	var preserveLastCode = document.forms.optionsForm.preserveLastCode.checked;
	var replaceNewTab = document.forms.optionsForm.replaceNewTab.checked;

	chrome.storage.sync.set({
		preserveLastCode: preserveLastCode,
		replaceNewTab: replaceNewTab
	}, function() {
		var status = document.getElementById('js-status');
		status.textContent = 'Settings saved.';
		setTimeout(function() {
			status.innerHTML = ' ';
		}, 750);
	});

	e.preventDefault();
}

document.addEventListener('DOMContentLoaded', restoreOptions);
document.forms.optionsForm.addEventListener('submit',
	saveOptions);<|endoftext|>


<commit_before>var path = require( 'path' );

module.exports = {
  pkgJSONPath: path.resolve( __dirname, '../package.json' ),
  configFile: {
    //defaultName: 'package.json',
    //pathToLocalConfig: path.resolve( __dirname, '../configs/bundly.json' ),
    description: 'Path to your `bundly` config. This can be used to specify the options instead of passing them on the command line'
  },
  //useDefaultOptions: true,
  optionator: {
    prepend: '`bundly` is a `watchify`/`browserify` wrapper with some useful preconfigured transforms and cache support\nto make it incremental builds even without the watch mode\n\n========================================================\nUsage: bundly -c bundly.conf.js\n       bundly [options] -o outfile.js entry-file.js\n========================================================',
    options: [
      {
        heading: 'Options'
      },
      {
        option: 'use-cache',
        alias: 'u',
        type: 'Boolean',
        default: 'true',
        description: 'Whether or not to remember the files and contents and only operate on the changed files to create incremental builds. By default is true'
      },
      {
        option: 'watch',
        alias: 'w',
        type: 'Boolean',
        description: 'Continuosly watch for changes of the files and do incremental builds'
      },
      {
        option: 'minimize',
        alias: 'm',
        type: 'Boolean',
        description: 'Whether to minimize or not the output or not. By default is `false`. When the flag is set both the non minimified and minified versions will be created'
      },
      {
        option: 'output-file',
        alias: 'o',
        type: 'String',
        description: 'The path and name for the output file'
      },
      {
        option: 'revision',
        alias: 'r',
        type: 'String',
        description: 'The revision to use in the generated file names'
      },
      {
        option: 'banner',
        alias: 'b',
        type: 'String',
        description: 'The banner to put at the top of the compiled files'
      },
      {
        option: 'target',
        alias: 't',
        type: 'String',
        dependsOn: 'config',
        description: 'The name of the target to execute from all the posible targets'
      }
    ]
  }
};
<commit_msg>FIX: setting the cache to false from the config should destroy the cache<commit_after>var path = require( 'path' );

module.exports = {
  pkgJSONPath: path.resolve( __dirname, '../package.json' ),
  configFile: {
    //defaultName: 'package.json',
    //pathToLocalConfig: path.resolve( __dirname, '../configs/bundly.json' ),
    description: 'Path to your `bundly` config. This can be used to specify the options instead of passing them on the command line'
  },
  //useDefaultOptions: true,
  optionator: {
    prepend: '`bundly` is a `watchify`/`browserify` wrapper with some useful preconfigured transforms and cache support\nto make it incremental builds even without the watch mode\n\n========================================================\nUsage: bundly -c bundly.conf.js\n       bundly [options] -o outfile.js entry-file.js\n========================================================',
    options: [
      {
        heading: 'Options'
      },
      {
        option: 'use-cache',
        alias: 'u',
        type: 'Boolean',
        //default: 'true',
        description: 'Whether or not to remember the files and contents and only operate on the changed files to create incremental builds. By default is true'
      },
      {
        option: 'watch',
        alias: 'w',
        type: 'Boolean',
        description: 'Continuosly watch for changes of the files and do incremental builds'
      },
      {
        option: 'minimize',
        alias: 'm',
        type: 'Boolean',
        description: 'Whether to minimize or not the output or not. By default is `false`. When the flag is set both the non minimified and minified versions will be created'
      },
      {
        option: 'output-file',
        alias: 'o',
        type: 'String',
        description: 'The path and name for the output file'
      },
      {
        option: 'revision',
        alias: 'r',
        type: 'String',
        description: 'The revision to use in the generated file names'
      },
      {
        option: 'banner',
        alias: 'b',
        type: 'String',
        description: 'The banner to put at the top of the compiled files'
      },
      {
        option: 'target',
        alias: 't',
        type: 'String',
        dependsOn: 'config',
        description: 'The name of the target to execute from all the posible targets'
      }
    ]
  }
};
<|endoftext|>


<commit_before>import md5 from 'md5';

import {
  BinaryFile,
  SourceFile,
  validateType
} from './';

/**
 * @param scripts An array of HTMLScriptElement (<script>)
 */
export default function makeFromElements(scripts) {
  return Promise.all(Array.from(scripts).map(makeFromElement));
}

function makeFromElement(script) {
  const name = script.getAttribute('name');
  const type = script.getAttribute('data-type');
  const options = {
    isEntryPoint: script.hasAttribute('is-entry-point'),
    isReadOnly: script.hasAttribute('is-read-only'),
    isTrashed: script.hasAttribute('is-trashed'),
    noBabel: script.hasAttribute('no-babel'),
  };
  const credits = script.hasAttribute('data-credits') ?
    JSON.parse(script.getAttribute('data-credits')) : [];

  const text = (code => {
    // Indent
    code = code.replace(/^\n*/g, '');
    const spaces = /^\s*/.exec(code)[0];
    if (spaces) {
      code = code
        .split('\n')
        .map(s => s.indexOf(spaces) ? s :  s.substr(spaces.length))
        .join('\n');
    }
    return code;
  })(script.textContent);

  if (validateType('text', type)) {
    return new SourceFile({ type, name, text, options, credits });
  }
  if (validateType('blob', type)) {

    const bin = atob(text);
    let byteArray = new Uint8Array(bin.length);
    for (let i = bin.length - 1; i >= 0; i--) {
      byteArray[i] = bin.charCodeAt(i);
    }
    const blob = new Blob([byteArray.buffer], { type });
    const hash = md5(byteArray);

    return new BinaryFile({ type, name, blob, options, credits, hash });
  }

  return Promise.reject('Unknown File Type' . file.type);
}
<commit_msg>bug fix<commit_after>import md5 from 'md5';

import {
  BinaryFile,
  SourceFile,
  validateType
} from './';

/**
 * @param scripts An array of HTMLScriptElement (<script>)
 */
export default function makeFromElements(scripts) {
  return Promise.all(Array.from(scripts).map(makeFromElement));
}

function makeFromElement(script) {
  const name = script.getAttribute('name');
  const type = script.getAttribute('data-type');
  const options = {
    isEntryPoint: script.hasAttribute('is-entry-point'),
    isReadOnly: script.hasAttribute('is-read-only'),
    isTrashed: script.hasAttribute('is-trashed'),
    noBabel: script.hasAttribute('no-babel'),
  };
  const credits = script.hasAttribute('data-credits') ?
    JSON.parse(script.getAttribute('data-credits')) : [];

  const text = (code => {
    // Indent
    code = code.replace(/^\n*/g, '');
    const spaces = /^\s*/.exec(code)[0];
    if (spaces) {
      code = code
        .split('\n')
        .map(s => s.indexOf(spaces) ? s :  s.substr(spaces.length))
        .join('\n');
    }
    return code;
  })(script.textContent);

  if (validateType('text', type)) {
    return new SourceFile({ type, name, text, options, credits });
  }
  if (validateType('blob', type)) {

    const bin = atob(text);
    let byteArray = new Uint8Array(bin.length);
    for (let i = bin.length - 1; i >= 0; i--) {
      byteArray[i] = bin.charCodeAt(i);
    }
    const blob = new Blob([byteArray.buffer], { type });
    const hash = md5(byteArray);

    return new BinaryFile({ type, name, blob, options, credits, hash });
  }

  return Promise.reject('Unknown File Type ' + type);
}
<|endoftext|>


<commit_before>import classNames from 'classnames/dedupe';
import React from 'react';

import BindMixin from '../Mixin/BindMixin';
import IconRadioButton from './icons/IconRadioButton';
import Util from '../Util/Util';

class FieldRadioButton extends Util.mixin(BindMixin) {
  get methodsToBind() {
    return ['handleChange'];
  }

  hasError() {
    let {props} = this;
    let validationError = props.validationError;

    return !!(validationError && validationError[props.name]);
  }

  getErrorMsg() {
    let {helpBlockClass, name, validationError} = this.props;

    if (!this.hasError()) {
      return null;
    }

    return (

        {validationError[name]}

    );
  }

  handleChange(eventName, name, event) {
    let {props} = this;

    if (eventName === 'multipleChange') {
      let model = props.startValue.reduce(function (changedItems, item) {
        if (item.checked && item.name !== name) {
          item.checked = false;
          changedItems.push(item);
        }

        return changedItems;
      }, [{name, checked: event.target.checked}]);

      props.handleEvent(eventName, props.name, model, event);
    }

    if (eventName === 'change') {
      props.handleEvent(eventName, props.name, event.target.checked, event);
    }
  }

  getLabel() {
    let {showLabel, name} = this.props;
    let label = name;

    if (!showLabel) {
      return null;
    }

    if (typeof showLabel === 'string') {
      label = showLabel;
    }

    if (typeof showLabel !== 'string' && showLabel !== true) {
      return showLabel;
    }

    return (

{label}

    );
  }

  getItemLabel(attributes) {
    if (!attributes.label) {
      return null;
    }

    let radioButtonLabelClass = classNames(
      attributes.radioButtonLabelClass,
      this.props.radioButtonLabelClass
    );

    return (

        {attributes.label}

    );
  }

  getItem(eventName, labelClass, attributes, index) {
    let labelClasses = classNames(
      labelClass,
      {mute: attributes.disabled},
      attributes.labelClass
    );

    return (

        <input
          onChange={this.handleChange.bind(this, eventName, attributes.name)}
          type="radio"
          {...attributes} />

          <IconRadioButton labelClass={labelClass} {...attributes} />

        {this.getItemLabel(attributes)}

    );
  }

  getItems() {
    let {labelClass, startValue} = this.props;

    if (!Util.isArray(startValue)) {
      // Fetch other attributes from props
      let value = {};
      if (startValue != null) {
        value.checked = startValue;
      }
      let model = Util.extend({}, this.props, value);

      return this.getItem('change', labelClass, model, 0);
    }

    return startValue.map(
      this.getItem.bind(this, 'multipleChange', labelClass)
    );
  }

  getRowClass() {
    let {columnWidth, formElementClass} = this.props;

    return classNames(`column-${columnWidth}`, formElementClass);
  }

  render() {
    let {formGroupClass, formGroupErrorClass} = this.props;

    let classes = classNames(formGroupClass, {
      [formGroupErrorClass]: this.hasError()
    });

    return (

          {this.getLabel()}
          {this.getItems()}
          {this.getErrorMsg()}

    );
  }
}

FieldRadioButton.defaultProps = {
  columnWidth: 12,
  formElementClass: 'form-row-element radio-button',
  handleEvent: function () {},
  labelClass: 'form-row-element form-element-radio-button',
  radioButtonLabelClass: 'form-element-radio-button-label'
};

let classPropType = React.PropTypes.oneOfType([
  React.PropTypes.array,
  React.PropTypes.object,
  React.PropTypes.string
]);

FieldRadioButton.propTypes = {
  // Optional number of columns to take up of the grid
  columnWidth: React.PropTypes.number.isRequired,
  // Function to handle change event
  // (usually passed down from form definition)
  handleEvent: React.PropTypes.func,
  // Optional boolean, string, or react node.
  // If boolean: true - shows name as label; false - shows nothing.
  // If string: shows string as label.
  // If node: returns the node as the label.
  showLabel: React.PropTypes.oneOfType([
    React.PropTypes.node,
    React.PropTypes.string,
    React.PropTypes.bool
  ]),
  // Attributes to pass to radio button(s)
  // (usually passed down from form definition)
  startValue: React.PropTypes.oneOfType([
    React.PropTypes.array,
    React.PropTypes.bool
  ]),
  // Optional object of error messages, with key equal to field property name
  validationError: React.PropTypes.object,

  // Classes
  formElementClass: classPropType,
  formGroupClass: classPropType,
  formGroupErrorClass: classPropType,
  helpBlockClass: classPropType,
  labelClass: classPropType,
  radioButtonLabelClass: classPropType
};

module.exports = FieldRadioButton;
<commit_msg>Creating wrapper class for radio button and checkbox to enable for more customizability<commit_after>import classNames from 'classnames/dedupe';
import React from 'react';

import BindMixin from '../Mixin/BindMixin';
import IconRadioButton from './icons/IconRadioButton';
import Util from '../Util/Util';

class FieldRadioButton extends Util.mixin(BindMixin) {
  get methodsToBind() {
    return ['handleChange'];
  }

  hasError() {
    let {props} = this;
    let validationError = props.validationError;

    return !!(validationError && validationError[props.name]);
  }

  getErrorMsg() {
    let {helpBlockClass, name, validationError} = this.props;

    if (!this.hasError()) {
      return null;
    }

    return (

        {validationError[name]}

    );
  }

  handleChange(eventName, name, event) {
    let {props} = this;

    if (eventName === 'multipleChange') {
      let model = props.startValue.reduce(function (changedItems, item) {
        if (item.checked && item.name !== name) {
          item.checked = false;
          changedItems.push(item);
        }

        return changedItems;
      }, [{name, checked: event.target.checked}]);

      props.handleEvent(eventName, props.name, model, event);
    }

    if (eventName === 'change') {
      props.handleEvent(eventName, props.name, event.target.checked, event);
    }
  }

  getLabel() {
    let {showLabel, name} = this.props;
    let label = name;

    if (!showLabel) {
      return null;
    }

    if (typeof showLabel === 'string') {
      label = showLabel;
    }

    if (typeof showLabel !== 'string' && showLabel !== true) {
      return showLabel;
    }

    return (

{label}

    );
  }

  getItemLabel(attributes) {
    if (!attributes.label) {
      return null;
    }

    let radioButtonLabelClass = classNames(
      attributes.radioButtonLabelClass,
      this.props.radioButtonLabelClass
    );

    return (

        {attributes.label}

    );
  }

  getItem(eventName, labelClass, attributes, index) {
    let labelClasses = classNames(
      labelClass,
      {mute: attributes.disabled},
      attributes.labelClass
    );

    return (

        <input
          onChange={this.handleChange.bind(this, eventName, attributes.name)}
          type="radio"
          {...attributes} />

          <IconRadioButton labelClass={labelClass} {...attributes} />

        {this.getItemLabel(attributes)}

    );
  }

  getItems() {
    let {labelClass, startValue} = this.props;

    if (!Util.isArray(startValue)) {
      // Fetch other attributes from props
      let value = {};
      if (startValue != null) {
        value.checked = startValue;
      }
      let model = Util.extend({}, this.props, value);

      return this.getItem('change', labelClass, model, 0);
    }

    return startValue.map(
      this.getItem.bind(this, 'multipleChange', labelClass)
    );
  }

  getRowClass() {
    let {columnWidth, formElementClass} = this.props;

    return classNames(`column-${columnWidth}`, formElementClass);
  }

  render() {
    let {formGroupClass, formGroupErrorClass, itemWrapperClasses} = this.props;

    let classes = classNames(formGroupClass, {
      [formGroupErrorClass]: this.hasError()
    });

    return (

          {this.getLabel()}

            {this.getItems()}

          {this.getErrorMsg()}

    );
  }
}

FieldRadioButton.defaultProps = {
  columnWidth: 12,
  formElementClass: 'form-row-element radio-button',
  handleEvent: function () {},
  labelClass: 'form-row-element form-element-radio-button',
  radioButtonLabelClass: 'form-element-radio-button-label'
};

let classPropType = React.PropTypes.oneOfType([
  React.PropTypes.array,
  React.PropTypes.object,
  React.PropTypes.string
]);

FieldRadioButton.propTypes = {
  // Optional number of columns to take up of the grid
  columnWidth: React.PropTypes.number.isRequired,
  // Function to handle change event
  // (usually passed down from form definition)
  handleEvent: React.PropTypes.func,
  // Optional boolean, string, or react node.
  // If boolean: true - shows name as label; false - shows nothing.
  // If string: shows string as label.
  // If node: returns the node as the label.
  showLabel: React.PropTypes.oneOfType([
    React.PropTypes.node,
    React.PropTypes.string,
    React.PropTypes.bool
  ]),
  // Attributes to pass to radio button(s)
  // (usually passed down from form definition)
  startValue: React.PropTypes.oneOfType([
    React.PropTypes.array,
    React.PropTypes.bool
  ]),
  // Optional object of error messages, with key equal to field property name
  validationError: React.PropTypes.object,

  // Classes
  formElementClass: classPropType,
  formGroupClass: classPropType,
  formGroupErrorClass: classPropType,
  helpBlockClass: classPropType,
  labelClass: classPropType,
  radioButtonLabelClass: classPropType
};

module.exports = FieldRadioButton;
<|endoftext|>