<commit_before>angular.module("umbraco")
    .controller("Umbraco.PropertyEditors.RelatedLinksController",
        function ($rootScope, $scope, dialogService, iconHelper) {

            if (!$scope.model.value) {
                $scope.model.value = [];
            }

            $scope.model.config.max = isNumeric($scope.model.config.max) && $scope.model.config.max !== 0 ? $scope.model.config.max : Number.MAX_VALUE;

            $scope.newCaption = '';
            $scope.newLink = 'http://';
            $scope.newNewWindow = false;
            $scope.newInternal = null;
            $scope.newInternalName = '';
            $scope.newInternalIcon = null;
            $scope.addExternal = true;
            $scope.currentEditLink = null;
            $scope.hasError = false;

            $scope.internal = function($event) {

               $scope.currentEditLink = null;

               $scope.contentPickerOverlay = {};
               $scope.contentPickerOverlay.view = "contentpicker";
               $scope.contentPickerOverlay.multiPicker = false;
               $scope.contentPickerOverlay.show = true;
               $scope.contentPickerOverlay.idType = $scope.model.config.idType ? $scope.model.config.idType : "int";

               $scope.contentPickerOverlay.submit = function(model) {

                  select(model.selection[0]);

                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $scope.contentPickerOverlay.close = function(oldModel) {
                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $event.preventDefault();
            };

            $scope.selectInternal = function($event, link) {

               $scope.currentEditLink = link;

               $scope.contentPickerOverlay = {};
               $scope.contentPickerOverlay.view = "contentpicker";
               $scope.contentPickerOverlay.multiPicker = false;
               $scope.contentPickerOverlay.show = true;

               $scope.contentPickerOverlay.submit = function(model) {

                  select(model.selection[0]);

                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $scope.contentPickerOverlay.close = function(oldModel) {
                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $event.preventDefault();

            };

            $scope.edit = function (idx) {
                for (var i = 0; i < $scope.model.value.length; i++) {
                    $scope.model.value[i].edit = false;
                }
                $scope.model.value[idx].edit = true;
            };

            $scope.saveEdit = function (idx) {
                $scope.model.value[idx].title = $scope.model.value[idx].caption;
                $scope.model.value[idx].edit = false;
            };

            $scope.delete = function (idx) {
                $scope.model.value.splice(idx, 1);
            };

            $scope.add = function ($event) {
                if ($scope.newCaption == "") {
                    $scope.hasError = true;
                } else {
                    if ($scope.addExternal) {
                        var newExtLink = new function() {
                            this.caption = $scope.newCaption;
                            this.link = $scope.newLink;
                            this.newWindow = $scope.newNewWindow;
                            this.edit = false;
                            this.isInternal = false;
                            this.type = "external";
                            this.title = $scope.newCaption;
                        };
                        $scope.model.value.push(newExtLink);
                    } else {
                        var newIntLink = new function() {
                            this.caption = $scope.newCaption;
                            this.link = $scope.newInternal;
                            this.newWindow = $scope.newNewWindow;
                            this.internal = $scope.newInternal;
                            this.edit = false;
                            this.isInternal = true;
                            this.internalName = $scope.newInternalName;
                            this.internalIcon = $scope.newInternalIcon;
                            this.type = "internal";
                            this.title = $scope.newCaption;
                        };
                        $scope.model.value.push(newIntLink);
                    }
                    $scope.newCaption = '';
                    $scope.newLink = 'http://';
                    $scope.newNewWindow = false;
                    $scope.newInternal = null;
                    $scope.newInternalName = '';
                    $scope.newInternalIcon = null;
                }
                $event.preventDefault();
            };

            $scope.switch = function ($event) {
                $scope.addExternal = !$scope.addExternal;
                $event.preventDefault();
            };

            $scope.switchLinkType = function ($event, link) {
                link.isInternal = !link.isInternal;
                link.type = link.isInternal ? "internal" : "external";
                if (!link.isInternal)
                    link.link = $scope.newLink;
                $event.preventDefault();
            };

            $scope.move = function (index, direction) {
                var temp = $scope.model.value[index];
                $scope.model.value[index] = $scope.model.value[index + direction];
                $scope.model.value[index + direction] = temp;
            };

            //helper for determining if a user can add items
            $scope.canAdd = function () {
                return $scope.model.config.max <= 0 || $scope.model.config.max > countVisible();
            }

            //helper that returns if an item can be sorted
            $scope.canSort = function () {
                return countVisible() > 1;
            }

            $scope.sortableOptions = {
                axis: 'y',
                handle: '.handle',
                cursor: 'move',
                cancel: '.no-drag',
                containment: 'parent',
                placeholder: 'sortable-placeholder',
                forcePlaceholderSize: true,
                helper: function (e, ui) {
                    // When sorting table rows, the cells collapse. This helper fixes that: http://www.foliotek.com/devblog/make-table-rows-sortable-using-jquery-ui-sortable/
                    ui.children().each(function () {
                        $(this).width($(this).width());
                    });
                    return ui;
                },
                items: '> tr:not(.unsortable)',
                tolerance: 'pointer',
                update: function (e, ui) {
                    // Get the new and old index for the moved element (using the URL as the identifier)
                    var newIndex = ui.item.index();
                    var movedLinkUrl = ui.item.attr('data-link');
                    var originalIndex = getElementIndexByUrl(movedLinkUrl);

                    // Move the element in the model
                    var movedElement = $scope.model.value[originalIndex];
                    $scope.model.value.splice(originalIndex, 1);
                    $scope.model.value.splice(newIndex, 0, movedElement);
                },
                start: function (e, ui) {
                    //ui.placeholder.html("	");

                    // Build a placeholder cell that spans all the cells in the row: http://stackoverflow.com/questions/25845310/jquery-ui-sortable-and-table-cell-size
                    var cellCount = 0;
                    $('td, th', ui.helper).each(function () {
                        // For each td or th try and get it's colspan attribute, and add that or 1 to the total
                        var colspan = 1;
                        var colspanAttr = $(this).attr('colspan');
                        if (colspanAttr > 1) {
                            colspan = colspanAttr;
                        }
                        cellCount += colspan;
                    });

                    // Add the placeholder UI - note that this is the item's content, so td rather than tr - and set height of tr
                    ui.placeholder.html('	').height(ui.item.height());
                }
            };

            //helper to count what is visible
            function countVisible() {
                return $scope.model.value.length;
            }

            function isNumeric(n) {
                return !isNaN(parseFloat(n)) && isFinite(n);
            }

            function getElementIndexByUrl(url) {
                for (var i = 0; i < $scope.model.value.length; i++) {
                    if ($scope.model.value[i].link == url) {
                        return i;
                    }
                }

                return -1;
            }

            function select(data) {
                if ($scope.currentEditLink != null) {
                    $scope.currentEditLink.internal = data.id;
                    $scope.currentEditLink.internalName = data.name;
                    $scope.currentEditLink.internalIcon = iconHelper.convertFromLegacyIcon(data.icon);
                    $scope.currentEditLink.link = data.id;
                } else {
                    $scope.newInternal = $scope.model.config.idType === "udi" ? data.udi : data.id;
                    $scope.newInternalName = data.name;
                    $scope.newInternalIcon = iconHelper.convertFromLegacyIcon(data.icon);
                }
            }
        });
<commit_msg>Adds in more checks for the UDI or int to be stored - as there is a similar call to open the dialog to pick content from another function name - unknown why Same for persisting data<commit_after>angular.module("umbraco")
    .controller("Umbraco.PropertyEditors.RelatedLinksController",
        function ($rootScope, $scope, dialogService, iconHelper) {

            if (!$scope.model.value) {
                $scope.model.value = [];
            }

            $scope.model.config.max = isNumeric($scope.model.config.max) && $scope.model.config.max !== 0 ? $scope.model.config.max : Number.MAX_VALUE;

            $scope.newCaption = '';
            $scope.newLink = 'http://';
            $scope.newNewWindow = false;
            $scope.newInternal = null;
            $scope.newInternalName = '';
            $scope.newInternalIcon = null;
            $scope.addExternal = true;
            $scope.currentEditLink = null;
            $scope.hasError = false;

            $scope.internal = function($event) {
               $scope.currentEditLink = null;

               $scope.contentPickerOverlay = {};
               $scope.contentPickerOverlay.view = "contentpicker";
               $scope.contentPickerOverlay.multiPicker = false;
               $scope.contentPickerOverlay.show = true;
               $scope.contentPickerOverlay.idType = $scope.model.config.idType ? $scope.model.config.idType : "int";

               $scope.contentPickerOverlay.submit = function(model) {

                  select(model.selection[0]);

                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $scope.contentPickerOverlay.close = function(oldModel) {
                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $event.preventDefault();
            };

            $scope.selectInternal = function ($event, link) {
               $scope.currentEditLink = link;

               $scope.contentPickerOverlay = {};
               $scope.contentPickerOverlay.view = "contentpicker";
               $scope.contentPickerOverlay.multiPicker = false;
               $scope.contentPickerOverlay.show = true;
               $scope.contentPickerOverlay.idType = $scope.model.config.idType ? $scope.model.config.idType : "int";

               $scope.contentPickerOverlay.submit = function(model) {

                  select(model.selection[0]);

                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $scope.contentPickerOverlay.close = function(oldModel) {
                  $scope.contentPickerOverlay.show = false;
                  $scope.contentPickerOverlay = null;
               };

               $event.preventDefault();

            };

            $scope.edit = function (idx) {
                for (var i = 0; i < $scope.model.value.length; i++) {
                    $scope.model.value[i].edit = false;
                }
                $scope.model.value[idx].edit = true;
            };

            $scope.saveEdit = function (idx) {
                $scope.model.value[idx].title = $scope.model.value[idx].caption;
                $scope.model.value[idx].edit = false;
            };

            $scope.delete = function (idx) {
                $scope.model.value.splice(idx, 1);
            };

            $scope.add = function ($event) {
                if ($scope.newCaption == "") {
                    $scope.hasError = true;
                } else {
                    if ($scope.addExternal) {
                        var newExtLink = new function() {
                            this.caption = $scope.newCaption;
                            this.link = $scope.newLink;
                            this.newWindow = $scope.newNewWindow;
                            this.edit = false;
                            this.isInternal = false;
                            this.type = "external";
                            this.title = $scope.newCaption;
                        };
                        $scope.model.value.push(newExtLink);
                    } else {
                        var newIntLink = new function() {
                            this.caption = $scope.newCaption;
                            this.link = $scope.newInternal;
                            this.newWindow = $scope.newNewWindow;
                            this.internal = $scope.newInternal;
                            this.edit = false;
                            this.isInternal = true;
                            this.internalName = $scope.newInternalName;
                            this.internalIcon = $scope.newInternalIcon;
                            this.type = "internal";
                            this.title = $scope.newCaption;
                        };
                        $scope.model.value.push(newIntLink);
                    }
                    $scope.newCaption = '';
                    $scope.newLink = 'http://';
                    $scope.newNewWindow = false;
                    $scope.newInternal = null;
                    $scope.newInternalName = '';
                    $scope.newInternalIcon = null;
                }
                $event.preventDefault();
            };

            $scope.switch = function ($event) {
                $scope.addExternal = !$scope.addExternal;
                $event.preventDefault();
            };

            $scope.switchLinkType = function ($event, link) {
                link.isInternal = !link.isInternal;
                link.type = link.isInternal ? "internal" : "external";
                if (!link.isInternal)
                    link.link = $scope.newLink;
                $event.preventDefault();
            };

            $scope.move = function (index, direction) {
                var temp = $scope.model.value[index];
                $scope.model.value[index] = $scope.model.value[index + direction];
                $scope.model.value[index + direction] = temp;
            };

            //helper for determining if a user can add items
            $scope.canAdd = function () {
                return $scope.model.config.max <= 0 || $scope.model.config.max > countVisible();
            }

            //helper that returns if an item can be sorted
            $scope.canSort = function () {
                return countVisible() > 1;
            }

            $scope.sortableOptions = {
                axis: 'y',
                handle: '.handle',
                cursor: 'move',
                cancel: '.no-drag',
                containment: 'parent',
                placeholder: 'sortable-placeholder',
                forcePlaceholderSize: true,
                helper: function (e, ui) {
                    // When sorting table rows, the cells collapse. This helper fixes that: http://www.foliotek.com/devblog/make-table-rows-sortable-using-jquery-ui-sortable/
                    ui.children().each(function () {
                        $(this).width($(this).width());
                    });
                    return ui;
                },
                items: '> tr:not(.unsortable)',
                tolerance: 'pointer',
                update: function (e, ui) {
                    // Get the new and old index for the moved element (using the URL as the identifier)
                    var newIndex = ui.item.index();
                    var movedLinkUrl = ui.item.attr('data-link');
                    var originalIndex = getElementIndexByUrl(movedLinkUrl);

                    // Move the element in the model
                    var movedElement = $scope.model.value[originalIndex];
                    $scope.model.value.splice(originalIndex, 1);
                    $scope.model.value.splice(newIndex, 0, movedElement);
                },
                start: function (e, ui) {
                    //ui.placeholder.html("	");

                    // Build a placeholder cell that spans all the cells in the row: http://stackoverflow.com/questions/25845310/jquery-ui-sortable-and-table-cell-size
                    var cellCount = 0;
                    $('td, th', ui.helper).each(function () {
                        // For each td or th try and get it's colspan attribute, and add that or 1 to the total
                        var colspan = 1;
                        var colspanAttr = $(this).attr('colspan');
                        if (colspanAttr > 1) {
                            colspan = colspanAttr;
                        }
                        cellCount += colspan;
                    });

                    // Add the placeholder UI - note that this is the item's content, so td rather than tr - and set height of tr
                    ui.placeholder.html('	').height(ui.item.height());
                }
            };

            //helper to count what is visible
            function countVisible() {
                return $scope.model.value.length;
            }

            function isNumeric(n) {
                return !isNaN(parseFloat(n)) && isFinite(n);
            }

            function getElementIndexByUrl(url) {
                for (var i = 0; i < $scope.model.value.length; i++) {
                    if ($scope.model.value[i].link == url) {
                        return i;
                    }
                }

                return -1;
            }

            function select(data) {
                if ($scope.currentEditLink != null) {
                    $scope.currentEditLink.internal = $scope.model.config.idType === "udi" ? data.udi : data.id;
                    $scope.currentEditLink.internalName = data.name;
                    $scope.currentEditLink.internalIcon = iconHelper.convertFromLegacyIcon(data.icon);
                    $scope.currentEditLink.link = $scope.model.config.idType === "udi" ? data.udi : data.id;
                } else {
                    $scope.newInternal = $scope.model.config.idType === "udi" ? data.udi : data.id;
                    $scope.newInternalName = data.name;
                    $scope.newInternalIcon = iconHelper.convertFromLegacyIcon(data.icon);
                }
            }
        });
<|endoftext|>


<commit_before>'use strict';

var isJpg = require('is-jpg');
var path = require('path');
var read = require('vinyl-file').read;
var targz = require('../');
var test = require('ava');

test('decompress a TAR.GZ file', function (t) {
	t.plan(2);

	read(path.join(__dirname, 'fixtures/test.tar.gz'), function (err, file) {
		t.assert(!err);

		var stream = targz();

		stream.on('data', function (file) {
			t.assert(isJpg(file.contents));
		});

		stream.end(file);
	});
});

test('strip path level using the `strip` option', function (t) {
	t.plan(3);

	read(path.join(__dirname, 'fixtures/test-nested.tar.gz'), function (err, file) {
		t.assert(!err);

		var stream = targz({ strip: 1 });

		stream.on('data', function (file) {
			t.assert(file.path === 'test.jpg');
			t.assert(isJpg(file.contents));
		});

		stream.end(file);
	});
});
<commit_msg>Show errors in tests<commit_after>'use strict';

var isJpg = require('is-jpg');
var path = require('path');
var read = require('vinyl-file').read;
var targz = require('../');
var test = require('ava');

test('decompress a TAR.GZ file', function (t) {
	t.plan(2);

	read(path.join(__dirname, 'fixtures/test.tar.gz'), function (err, file) {
		t.assert(!err, err);

		var stream = targz();

		stream.on('data', function (file) {
			t.assert(isJpg(file.contents));
		});

		stream.end(file);
	});
});

test('strip path level using the `strip` option', function (t) {
	t.plan(3);

	read(path.join(__dirname, 'fixtures/test-nested.tar.gz'), function (err, file) {
		t.assert(!err, err);

		var stream = targz({ strip: 1 });

		stream.on('data', function (file) {
			t.assert(file.path === 'test.jpg');
			t.assert(isJpg(file.contents));
		});

		stream.end(file);
	});
});
<|endoftext|>


<commit_before>/*global describe, it */
'use strict';

var assert = require('assert');
var binCheck = require('../');
var path = require('path');

describe('binCheck()', function () {
    it('should test a binary and return true', function (cb) {
        var bin = path.join(__dirname, 'fixtures/optipng-linux');

        if (process.platform === 'darwin') {
            bin = path.join(__dirname, 'fixtures/optipng-osx');
        } else if (process.platform === 'win32') {
            bin = path.join(__dirname, 'fixtures/optipng-win32.exe');
        }

        binCheck(bin, '--version', function (err, works, msg) {
            assert(msg.indexOf('0.7.4'));
            assert(works);
            cb();
        });
    });
});
<commit_msg>Only check if there is a message<commit_after>/*global describe, it */
'use strict';

var assert = require('assert');
var binCheck = require('../');
var path = require('path');

describe('binCheck()', function () {
    it('should test a binary and return true', function (cb) {
        var bin = path.join(__dirname, 'fixtures/optipng-linux');

        if (process.platform === 'darwin') {
            bin = path.join(__dirname, 'fixtures/optipng-osx');
        } else if (process.platform === 'win32') {
            bin = path.join(__dirname, 'fixtures/optipng-win32.exe');
        }

        binCheck(bin, '--version', function (err, works, msg) {
            if (msg) {
                assert(msg.indexOf('0.7.4') !== -1);
            }

            assert(works);
            cb();
        });
    });
});
<|endoftext|>


<commit_before>var assert=require('assert'), fs=require('fs'),  path=require('path'),
  Log=require('..'), file=__dirname+'/tmp'+Date.now()+'.log';

describe('Vinvocci', function() {
  var log=new Log(), res;

  it('should log to stdout', function() {
    res=getOutput(function() {
      log.info('test');
    });
    assert.equal(res[0].msg, 'test');
  });

  it('should log time', function() {
    assert(res[0].time);
  });

  it('should log INFO and ERROR', function() {
    res=getOutput(function() {
      log.info('test');
      log.error('test');
      log.debug('nope');
    });
    assert.equal(res[0].msg, 'test');
    assert.equal(res[0].type, 'INFO');
    assert.equal(res[1].type, 'ERROR');
  });

  it('should supress DEBUG', function() {
    assert.equal(res[2], undefined);
  });

  it('should accept string as log level', function() {
    log.setLevel('eRRor');
    res=getOutput(function() {
      log.info('test1');
      log.error('test2');
    });
    assert.equal(res[0].msg, 'test2');
    assert.equal(res[0].type, 'ERROR');
    assert.equal(res[1], undefined);
  });

  it('should set log level to DEBUG', function() {
    log.setLevel(Log.DEBUG);
    res=getOutput(function() {
      log.debug('test');
    });
    assert.equal(res[0].msg, 'test');
    assert.equal(res[0].type, 'DEBUG');
  });

  it('should log component when set', function() {
    res=getOutput(function() {
      log.debug('test1');
      log.component='compo';
      log.info('test2');
    });
    assert.equal(res[0].component, undefined);
    assert.equal(res[1].component, 'compo');
  });

  it('should change component property name', function() {
    res=getOutput(function() {
      log.componentProp='app';
      log.debug('test1');
    });
    assert.equal(res[0].component, undefined);
    assert.equal(res[0].app, 'compo');
  });

  it('should log to file', function(done) {
    log=new Log(null, null, file);
    log.info('test1');
    setTimeout(function() {
      res=convertToArray(fs.readFileSync(file));
      assert.equal(res[0].msg, 'test1');
      done();
    }, 30);
  });

  it('should append to file', function(done) {
    log=new Log(null, null, file);
    log.info('test2');
    setTimeout(function() {
      res=convertToArray(fs.readFileSync(file));
      assert.equal(res[0].msg, 'test1');
      assert.equal(res[1].msg, 'test2');
      done();
    }, 30);
  });

  it('should remove test log file', function() {
    fs.unlinkSync(file);
  });

});

function getOutput(cb) {
  var write=process.stdout.write, buf='';
  process.stdout.write=function(data) {
    buf+=data;
  };
  cb();
  process.stdout.write=write;
  return convertToArray(buf);
}

function convertToArray(str) {
  return JSON.parse('['+str.toString().trim().replace(/\n/g, ',')+']');
}
<commit_msg>fixed a bug in tests<commit_after>var assert=require('assert'), fs=require('fs'),  path=require('path'),
  Log=require('..'), file=__dirname+'/tmp'+Date.now()+'.log';

describe('Vinvocci', function() {
  var log=new Log(), res;

  it('should log to stdout', function() {
    res=getOutput(function() {
      log.info('test');
    });
    assert.equal(res[0].msg, 'test');
  });

  it('should log time', function() {
    assert(res[0].time);
  });

  it('should log INFO and ERROR', function() {
    res=getOutput(function() {
      log.info('test');
      log.error('test');
      log.debug('nope');
    });
    assert.equal(res[0].msg, 'test');
    assert.equal(res[0].type, 'INFO');
    assert.equal(res[1].type, 'ERROR');
  });

  it('should supress DEBUG', function() {
    assert.equal(res[2], undefined);
  });

  it('should accept string as log level', function() {
    log.setLevel('eRRor');
    res=getOutput(function() {
      log.info('test1');
      log.error('test2');
    });
    assert.equal(res[0].msg, 'test2');
    assert.equal(res[0].type, 'ERROR');
    assert.equal(res[1], undefined);
  });

  it('should set log level to DEBUG', function() {
    log.setLevel(Log.DEBUG);
    res=getOutput(function() {
      log.debug('test');
    });
    assert.equal(res[0].msg, 'test');
    assert.equal(res[0].type, 'DEBUG');
  });

  it('should log component when set', function() {
    res=getOutput(function() {
      log.debug('test1');
      log.component='compo';
      log.info('test2');
    });
    assert.equal(res[0].component, undefined);
    assert.equal(res[1].component, 'compo');
  });

  it('should change component property name', function() {
    res=getOutput(function() {
      log.componentProp='app';
      log.debug('test1');
    });
    assert.equal(res[0].component, undefined);
    assert.equal(res[0].app, 'compo');
  });

  it('should log to file', function(done) {
    log=new Log(null, null, file);
    log.info('test1');
    setTimeout(function() {
      res=convertToArray(fs.readFileSync(file));
      assert.equal(res[0].msg, 'test1');
      done();
    }, 30);
  });

  it('should append to file', function(done) {
    log=new Log(null, null, file);
    log.info('test2');
    setTimeout(function() {
      res=convertToArray(fs.readFileSync(file));
      assert.equal(res[0].msg, 'test1');
      assert.equal(res[1].msg, 'test2');
      done();
    }, 30);
  });

  it('should remove test log file', function() {
    fs.unlinkSync(file);
  });

});

function getOutput(cb) {
  var write=process.stdout.write, buf='';
  process.stdout.write=function(data) {
    buf+=data;
  };
  try {
    cb();
    process.stdout.write=write;
  } catch(err) {
    process.stdout.write=write;
    throw err;
  }
  return convertToArray(buf);
}

function convertToArray(str) {
  return JSON.parse('['+str.toString().trim().replace(/\n/g, ',')+']');
}
<|endoftext|>


<commit_before>'use strict';

require('should');
const checker = require('../index');
const os = require('os');
const execSync = require('child_process').execSync;

describe('check-branch', () => {
  const currentBranch = execSync('git status').toString().match(/^On\sbranch\s(.*)\s/)[1];
  before(() => execSync('git checkout -b testbranch', {
    stdio: 'pipe'
  }));
  after(() => {
    execSync(`git checkout ${currentBranch}`, {
      stdio: 'pipe'
    });
    execSync('git branch -D testbranch', {
      stdio: 'pipe'
    });
  });
  describe('success', () => {
    it('should resolve object with success true if in right branch', () => {
      return checker('testbranch').should.be.fulfilledWith({
        success: true,
        detail: 'testbranch'
      });
    });
  });
  describe('fail', () => {
    beforeEach(() => execSync('git checkout -b sometestbranch', {
      stdio: 'pipe'
    }));
    afterEach(() => {
      execSync('git checkout testbranch', {
        stdio: 'pipe'
      });
      execSync('git branch -D sometestbranch', {
        stdio: 'pipe'
      });
    });
    it('should resolve object with success false if not in right branch', () => {
      return checker('testbranch').should.be.fulfilledWith({
        success: false,
        detail: 'sometestbranch'
      });
    });
  });
  describe('error', () => {
    it('should reject with an error when branch is not a string', () => {
      return checker({}).should.be.rejectedWith(TypeError, {
        message: 'Expected branch to be a string'
      });
    });
    it('should reject with an error when cwd is not a string', () => {
      return checker('testbranch', {}).should.be.rejectedWith(TypeError, {
        message: 'Expected cwd to be a string'
      });
    });
    it('should reject with an error when no git repository found', () => {
      let dir = os.tmpdir();
      return checker('testbranch', dir).should.be.rejectedWith(Error, {
        message: `No git repository was found in ${dir}`
      });
    });
  });
});
<commit_msg>:smile:<commit_after>'use strict';

require('should');
const checker = require('../index');
const os = require('os');
const execSync = require('child_process').execSync;

describe('check-branch', () => {
  console.log(execSync('git status').toString());
  const currentBranch = execSync('git status').toString().match(/^On\sbranch\s(.*)\s/)[1];
  before(() => execSync('git checkout -b testbranch', {
    stdio: 'pipe'
  }));
  after(() => {
    execSync(`git checkout ${currentBranch}`, {
      stdio: 'pipe'
    });
    execSync('git branch -D testbranch', {
      stdio: 'pipe'
    });
  });
  describe('success', () => {
    it('should resolve object with success true if in right branch', () => {
      return checker('testbranch').should.be.fulfilledWith({
        success: true,
        detail: 'testbranch'
      });
    });
  });
  describe('fail', () => {
    beforeEach(() => execSync('git checkout -b sometestbranch', {
      stdio: 'pipe'
    }));
    afterEach(() => {
      execSync('git checkout testbranch', {
        stdio: 'pipe'
      });
      execSync('git branch -D sometestbranch', {
        stdio: 'pipe'
      });
    });
    it('should resolve object with success false if not in right branch', () => {
      return checker('testbranch').should.be.fulfilledWith({
        success: false,
        detail: 'sometestbranch'
      });
    });
  });
  describe('error', () => {
    it('should reject with an error when branch is not a string', () => {
      return checker({}).should.be.rejectedWith(TypeError, {
        message: 'Expected branch to be a string'
      });
    });
    it('should reject with an error when cwd is not a string', () => {
      return checker('testbranch', {}).should.be.rejectedWith(TypeError, {
        message: 'Expected cwd to be a string'
      });
    });
    it('should reject with an error when no git repository found', () => {
      let dir = os.tmpdir();
      return checker('testbranch', dir).should.be.rejectedWith(Error, {
        message: `No git repository was found in ${dir}`
      });
    });
  });
});
<|endoftext|>


<commit_before>function traverseDOM(node){
  var childLen=node.childNodes.length;
  if(childLen==0){
  }else{
    for(var i=0;i<childLen;i++){
      var childTmp=node.childNodes[i];
      if(childTmp.nodeType==1){
        if(childTmp.id=='tanx-popwin-outermm_51073678_5024723_5024723_15460009'){
          var str="hello world!";
        }
        var obj=window.getComputedStyle(childTmp);
        if(obj.hasOwnProperty("position")){
          if(obj.position=="fixed"){
            console.log("the fixed element");
            console.log(childTmp);
            childTmp.style.display="none";
            return;
          }
        }
      }
      traverseDOM(childTmp);
    }
  }
}

setTimeout(function(){
  traverseDOM(document.body);
},0);

<commit_msg>Update test.js<commit_after>function traverseDOM(node){
  var childLen=node.childNodes.length;
  if(childLen==0){
  }else{
    for(var i=0;i<childLen;i++){
      var childTmp=node.childNodes[i];
      if(childTmp.nodeType==1){
        if(childTmp.id=='tanx-popwin-outermm_51073678_5024723_15460009'){
          var str="hello world!";
        }
        var obj=window.getComputedStyle(childTmp);
        if(obj.hasOwnProperty("position")){
          if(obj.position=="fixed"){
            console.log("the fixed element");
            console.log(childTmp);
            childTmp.style.display="none";
            return;
          }
        }
      }
      traverseDOM(childTmp);
    }
  }
}

setTimeout(function(){
  traverseDOM(document.body);
},0);

<|endoftext|>


<commit_before>$(document).ready(function () {
    var body_height = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight;
    var body_width = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;
    $('.body').height(body_height - 100);

    //Create scaled canvas element
    var vert_percent = 1;
    var horz_percent = 1;
    var canv_width = horz_percent * body_width;
    var canv_height = vert_percent * (body_height - 100);
    var canv_def = "<canvas id='can' height='" + canv_height + "' width='" + canv_width + "'>Sorry, your browser does not support html5:(</canvas>";
    $('.body').append(canv_def);

    var ctx = document.getElementById('can').getContext('2d');
    var pressed = {};
    var Circle_array = [];
    var friction = 1;
    var delta_t = 0.05;
    var max_veloc = 20;

    function Circle(x, y, r, color) {
        this.x = x;
        this.y = y;
        this.r = r;
        this.color = color;
        this.x_veloc = 0;
        this.y_veloc = 0;
        //Mass is just equal to radius

        this.draw = function () {
            //ctx.clearRect(0,0,a_canvas.width,a_canvas.height);
            //console.log("drawing: "+this.name+":"+this.color);
            ctx.fillStyle = this.color;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
            ctx.fill();

            ctx.linewidth = 1;
            ctx.fillStyle = "black";
            ctx.stroke();
            ctx.closePath();
        };

        this.updatePosition = function (scale) {
            this.x_veloc += ((scale * Math.random()) - (scale / 2)) / this.r;
            this.y_veloc += ((scale * Math.random()) - (scale / 2)) / this.r;
            this.x_veloc /= friction;
            this.y_veloc /= friction;
            this.x_veloc = Math.min(this.x_veloc, max_veloc);
            this.y_veloc = Math.min(this.y_veloc, max_veloc);
            this.x += this.x_veloc * delta_t;
            this.y += this.y_veloc * delta_t;
            if (this.x > canv_width) {
                this.x %= canv_width;
            } else if (this.x < 0) {
                this.x = canv_width;
            }
            if (this.y > canv_height) {
                this.y %= canv_height;
            } else if (this.y < 0) {
                this.y = canv_height;
            }
        };
    }

    function setup() {
        document.addEventListener('keydown', function (e) {
            pressed[e.keyCode] = true;
        });
        document.addEventListener('keyup', function (e) {
            pressed[e.keyCode] = false;
        });
    }

    function updateGameState() {
        if (pressed[' '.charCodeAt(0)] == true) {
            var x = Math.random() * canv_width;
            var y = Math.random() * canv_height;
            var r = Math.random() * 35 + 3;
            console.log(x + " " + y);
            var color = "rgb(" + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + "," + Math.floor(Math.random() * 256) + ")";
            Circle_array.push(new Circle(x, y, r, color))
        }

        for (i = 0; i < Circle_array.length; i++) {
            var p = Circle_array[i];
            p.updatePosition(30);
        }
    }

    function draw() {
        ctx.clearRect(0, 0, canv_width, canv_height);
        for (i = 0; i < Circle_array.length; i++) {
            var p = Circle_array[i];
            p.draw();
        }
    }

    function gameLoop() {
        updateGameState();
        draw();
        window.requestAnimFrame(gameLoop);
    }

    window.requestAnimFrame = (function () {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    })();

    setup();
    window.requestAnimFrame(gameLoop);
});
<commit_msg>Tried to add age to the code so that bubbles would become transparent over time and eventually dissapear (and get removed from Circle_array so that they don't hog any more memory or get drawn), but I also changed the way that colors are handled and initialized (to an array rather than a string). Something broke.<commit_after>$(document).ready(function () {
    var body_height = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight;
    var body_width = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;
    $('.body').height(body_height - 100);

    //Create scaled canvas element
    var vert_percent = 1;
    var horz_percent = 1;
    var canv_width = horz_percent * body_width;
    var canv_height = vert_percent * (body_height - 100);
    var canv_def = "<canvas id='can' height='" + canv_height + "' width='" + canv_width + "'>Sorry, your browser does not support html5:(</canvas>";
    $('.body').append(canv_def);

    var ctx = document.getElementById('can').getContext('2d');
    var pressed = {}; //Used for getting user inputs
    var Circle_array = [];
    var friction = 1.1;
    var delta_t = 0.05;
    var max_veloc = 20;
    var count = -1; //Used as a unique ID for each circle
    var deletions = 0; //Used to modify the unique ID when deleting an element

    function Circle(x, y, r, color, count) {
        this.x = x;
        this.y = y;
        this.r = r;
        this.color = color;
	this.color.push(1);
        this.x_veloc = 0;
        this.y_veloc = 0;
	this.count = count;

        this.draw = function () {
            ctx.fillStyle = 'rgba('+this.color.join(',')+')';
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
            ctx.fill();
            ctx.linewidth = 1;
            ctx.fillStyle = "black";
            ctx.stroke();
            ctx.closePath();
        };

        this.updatePosition = function (scale) {
	    //Update velocities
            this.x_veloc += ((scale * Math.random()) - (scale / 2)) / this.r;
            this.y_veloc += ((scale * Math.random()) - (scale / 2)) / this.r;
            this.x_veloc /= friction;
            this.y_veloc /= friction;
            this.x_veloc = Math.min(this.x_veloc, max_veloc);
            this.y_veloc = Math.min(this.y_veloc, max_veloc);
	    //Update positions - make sure dot stays on canvas
            this.x += this.x_veloc * delta_t;
            this.y += this.y_veloc * delta_t;
            if (this.x > canv_width) {
                this.x %= canv_width;
            } else if (this.x < 0) {
                this.x = canv_width;
            }
            if (this.y > canv_height) {
                this.y %= canv_height;
            } else if (this.y < 0) {
                this.y = canv_height;
            }
	    //Update alpha
	    this.alpha *= .988514; //Sets half-life to about 1 second (60 frames, hopefully...)
        };
    }

    function getRGB() {
	return [Math.floor(Math.random()*256),Math.floor(Math.random()*256),Math.floor(Math.random()*256)];
    }

    function deleteCircle(circle) {
	Cirlce_array.splice(circle.count-deletions,1);
	deletions++;
    }

    function setup() {
        document.addEventListener('keydown', function (e) {
            pressed[e.keyCode] = true;
        });
        document.addEventListener('keyup', function (e) {
            pressed[e.keyCode] = false;
        });
    }

    function updateGameState() {
        if (pressed[' '.charCodeAt(0)] == true) {
	    count++;
            var x = Math.random() * canv_width;
            var y = Math.random() * canv_height;
            var r = Math.random() * 35 + 3;
            Circle_array.push(new Circle(x, y, r, getRGB(), count))
        }
        for (i = 0; i < Circle_array.length; i++) {
	    Circle_array[i].updatePosition();
        }
    }

    function draw() {
        ctx.clearRect(0, 0, canv_width, canv_height);
        for (i = 0; i < Circle_array.length; i++) {
	    if(Circle_array[i].alpha < .01) {
		deleteCircle(Circle_array[i]);
	    }
	    else {
		Circle_array[i].draw();
		console.log(Circle_array[i].color+','+Circle_array[i].count);
	    }
        }
    }

    function gameLoop() {
        updateGameState();
        draw();
        window.requestAnimFrame(gameLoop);
    }

    window.requestAnimFrame = (function () {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    })();

    setup();
    window.requestAnimFrame(gameLoop);
});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var test = require( 'tape' );
var isfinite = require( 'validate.io-finite' );
var isnan = require( 'validate.io-nan' );
var abs = require( 'math-abs' );
var betaln = require( './../lib' );

// FIXTURES //

var arg1 = require( './fixtures/arg1.json' );
var arg2 = require( './fixtures/arg2.json' );
var expected = require( './fixtures/expected.json' );
var i;
var v;
for ( i = 0; i < expected.length; i++ ) {
	v = expected[ i ];
	if ( v === 'Inf' ) {
		expected[ i ] = Number.POSITIVE_INFINITY;
	}
	else if ( v === 'NaN' ) {
		expected[ i ] = NaN;
	}
}

// TESTS //

test( 'main export is a function', function test( t ) {
	t.ok( typeof betaln === 'function', 'main export is a function' );
	t.end();
});

test( 'the function returns `NaN` if provided a `NaN`', function test( t ) {
	var val = betaln( NaN, 2 );
	t.notOk( val === val, 'returns NaN' );
	val = betaln( 2, NaN );
	t.notOk( val === val, 'returns NaN' );
	t.end();
});

test( 'the function returns `NaN` if provided negative values', function test( t ) {
	var val = betaln( -2, 5 );
	t.notOk( val === val, 'returns NaN' );
	val = betaln( 4, -3 );
	t.notOk( val === val, 'returns NaN' );
	t.end();
});

test( 'the function evaluates the logarithm of the beta function', function test( t ) {
	var actual;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < arg1.length; i++ ) {
		actual =  betaln( arg1[ i ], arg2[ i ] );

		b1 = isfinite( actual );
		b2 = isfinite( expected[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 ) {
			t.ok( abs( actual - expected[ i ] ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected[ i ] + '.' );
		}
	}
	t.end();
});
<commit_msg>Add tests for args equal to zero<commit_after>'use strict';

// MODULES //

var test = require( 'tape' );
var isfinite = require( 'validate.io-finite' );
var isnan = require( 'validate.io-nan' );
var abs = require( 'math-abs' );
var betaln = require( './../lib' );

// FIXTURES //

var arg1 = require( './fixtures/arg1.json' );
var arg2 = require( './fixtures/arg2.json' );
var expected = require( './fixtures/expected.json' );
var i;
var v;
for ( i = 0; i < expected.length; i++ ) {
	v = expected[ i ];
	if ( v === 'Inf' ) {
		expected[ i ] = Number.POSITIVE_INFINITY;
	}
	else if ( v === 'NaN' ) {
		expected[ i ] = NaN;
	}
}

// TESTS //

test( 'main export is a function', function test( t ) {
	t.ok( typeof betaln === 'function', 'main export is a function' );
	t.end();
});

test( 'the function returns `NaN` if provided a `NaN`', function test( t ) {
	var val = betaln( NaN, 2 );
	t.notOk( val === val, 'returns NaN' );
	val = betaln( 2, NaN );
	t.notOk( val === val, 'returns NaN' );
	t.end();
});

test( 'the function returns `NaN` if provided negative values', function test( t ) {
	var val = betaln( -2, 5 );
	t.notOk( val === val, 'returns NaN' );
	val = betaln( 4, -3 );
	t.notOk( val === val, 'returns NaN' );
	t.end();
});

test( 'the function returns +Infinity if at least one argument is zero', function test( t ) {
	var val = betaln( 0, 2 );
	t.ok( !isfinite( val ), 'returns +Infinity' );
	val = betaln( 1, 0 );
	t.ok( !isfinite( val ), 'returns +Infinity' );
	t.end();
});

test( 'the function evaluates the logarithm of the beta function', function test( t ) {
	var actual;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < arg1.length; i++ ) {
		actual =  betaln( arg1[ i ], arg2[ i ] );

		b1 = isfinite( actual );
		b2 = isfinite( expected[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 ) {
			t.ok( abs( actual - expected[ i ] ) < 1e-14, 'returned result is within tolerance. actual: ' + actual + '; expected: ' + expected[ i ] + '.' );
		}
	}
	t.end();
});
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var Joi = require('joi');
var async = require('async');
var Onion = require('lib-onion');

var ArrayTypeHandler = function(opts) {
	var typeFactory = opts.typeFactory;
  var chance = opts.chance;
  var debug = opts.debug;

  var onion = new Onion('array');

  var Min = function(msg, tests, next) {
    var min = _.find(tests, {
      name: 'min'
    });
    if (min) {
      min = min.arg;
      if (msg.num >= min) {
        // Message is OK as it is
        return next(null, msg, tests);
      }

      msg.num = chance.integer({
        min: min,
        max: 100
      });
    }
    next(null, msg, tests);
  };

  var Max = function(msg, tests, next) {
    /* jshint maxcomplexity: 6 */
    var max = _.find(tests, {
      name: 'max'
    });
    if (max) {
      max = max.arg;
      if (msg.num <= max) {
        // Message is OK as it is
        return next(null, msg, tests);
      }

      var min = _.find(tests, {
        name: 'min'
      });
      if (min) {
        min = min.arg;
        msg.num = chance.integer({
          min: min,
          max: max
        });
      } else {
        msg.num = chance.integer({
          min: 0,
          max: max
        });
      }
    }
    return next(null, msg, tests);
  };

  onion.add(Min, 'min');
  onion.add(Max, 'max');

	return {
		handle: function(schema, callback) {
			var output = {};

      // console.log(JSON.stringify(schema));
      onion.handle(output, schema._tests, function(err, output) {
        debug('output', output);
        var potentialSchemas = [];

        // For each of the items in the array definition...
        async.eachSeries(schema._inner.items, function(child, callback) {
          // Loop through each of the children of that defintion
          if(child._inner.children) {
            var item = {};
            async.eachSeries(child._inner.children, function(child, cb) {
              debug('doing child element', child.key, child.schema._type);
              item[child.key] = child.schema;
              cb();
            }, function(err) {
              potentialSchemas.push(Joi.object(item));
              item = {};
              callback(err);
            });
          }
          else {
            potentialSchemas.push(child);
            callback();
          }
        }, function(err) {
          if(err) {
            return callback(err, null);
          }
          console.log(output.num);
          var schemaGenerators = new Array(output.num);
          _.fill(schemaGenerators, function(cb){
            var randomSchema = potentialSchemas[_.random(0,potentialSchemas.length - 1)];
            typeFactory.gimme(randomSchema, function(err, childHandler) {
              if(err) {
                return cb(err, null);
              }
              childHandler.handle(randomSchema, function(err, childResult) {
                debug('output', randomSchema.key, childResult);
                cb(err, childResult);
              });
            });
          });

          async.series(schemaGenerators, function(err, output){
            debug('output', output.msg);
            callback(err, output);
          });
        });
      });
		}
	};
};
module.exports = ArrayTypeHandler;
<commit_msg>- Remove console.log<commit_after>'use strict';
var _ = require('lodash');
var Joi = require('joi');
var async = require('async');
var Onion = require('lib-onion');

var ArrayTypeHandler = function(opts) {
	var typeFactory = opts.typeFactory;
  var chance = opts.chance;
  var debug = opts.debug;

  var onion = new Onion('array');

  var Min = function(msg, tests, next) {
    var min = _.find(tests, {
      name: 'min'
    });
    if (min) {
      min = min.arg;
      if (msg.num >= min) {
        // Message is OK as it is
        return next(null, msg, tests);
      }

      msg.num = chance.integer({
        min: min,
        max: 100
      });
    }
    next(null, msg, tests);
  };

  var Max = function(msg, tests, next) {
    /* jshint maxcomplexity: 6 */
    var max = _.find(tests, {
      name: 'max'
    });
    if (max) {
      max = max.arg;
      if (msg.num <= max) {
        // Message is OK as it is
        return next(null, msg, tests);
      }

      var min = _.find(tests, {
        name: 'min'
      });
      if (min) {
        min = min.arg;
        msg.num = chance.integer({
          min: min,
          max: max
        });
      } else {
        msg.num = chance.integer({
          min: 0,
          max: max
        });
      }
    }
    return next(null, msg, tests);
  };

  onion.add(Min, 'min');
  onion.add(Max, 'max');

	return {
		handle: function(schema, callback) {
			var output = {};

      onion.handle(output, schema._tests, function(err, output) {
        debug('output', output);
        var potentialSchemas = [];

        // For each of the items in the array definition...
        async.eachSeries(schema._inner.items, function(child, callback) {
          // Loop through each of the children of that defintion
          if(child._inner.children) {
            var item = {};
            async.eachSeries(child._inner.children, function(child, cb) {
              debug('doing child element', child.key, child.schema._type);
              item[child.key] = child.schema;
              cb();
            }, function(err) {
              potentialSchemas.push(Joi.object(item));
              item = {};
              callback(err);
            });
          }
          else {
            potentialSchemas.push(child);
            callback();
          }
        }, function(err) {
          if(err) {
            return callback(err, null);
          }
          var schemaGenerators = new Array(output.num);
          _.fill(schemaGenerators, function(cb){
            var randomSchema = potentialSchemas[_.random(0,potentialSchemas.length - 1)];
            typeFactory.gimme(randomSchema, function(err, childHandler) {
              if(err) {
                return cb(err, null);
              }
              childHandler.handle(randomSchema, function(err, childResult) {
                debug('output', randomSchema.key, childResult);
                cb(err, childResult);
              });
            });
          });

          async.series(schemaGenerators, function(err, output){
            debug('output', output.msg);
            callback(err, output);
          });
        });
      });
		}
	};
};
module.exports = ArrayTypeHandler;
<|endoftext|>


<commit_before>var root = require('root');
var request = require('request');
var common = require('common');
var immortal = require('immortal');
var announce = require('./announce');
var net = require('net');

var Bucket = common.emitter(function(uri) {
	this.uri = uri;
	this.all = {};
});

Bucket.prototype.keys = function() {
	return Object.keys(this.all);
};
Bucket.prototype.pushAll = function(vals) {
	var self = this;

	Object.keys(vals).forEach(function(key) {
		self.push(key, vals[key]);
	});
};
Bucket.prototype.push = function(key, val) {
	var list = this.all[key] = this.get(key);

	val = Array.isArray(val) ? val : [val];
	list.push.apply(list, val);
	this.emit('push', key, val);
};
Bucket.prototype.pop = function(key) {
	var list = this.all[key];

	if (!list) return;
	delete this.all[key];
	this.emit('pop', key, list);
};
Bucket.prototype.get = function(key) {
	return this.all[key] || [];
};
Bucket.prototype.destroy = function() {
	this.emit('destroy');
	this.keys().forEach(this.pop.bind(this));
};
Bucket.prototype.toJSON = function() {
	return this.all;
};

var PROXY = 'address get all push'.split(' ');
var PING_TIMEOUT = 10*0000;
var HEARTBEAT = 2*60*1000;
var ME = function() {
	var nets = require('os').networkInterfaces();

	for (var i in nets) {
		var candidate = nets[i].filter(function(item) {
			return item.family === 'IPv4' && !item.internal;
		})[0];

		if (candidate) {
			return candidate.address;
		}
	}

	return '127.0.0.1';
}();

var startMonitor = function(callback) {
	var retry = function() {
		connect(function(err, socket) {
			if (err) return setTimeout(retry, 100);
			callback(null, socket);
		});
	};
	var fork = function() {
		immortal.start(__dirname+'/monitor.js', {
			strategy: 'unattached',
			auto:false,
			monitor:null
		}, function() {
			retry();
		});
	};
	var connect = function(callback) {
		var socket = net.connect(67567, '127.0.0.1');
		var onerror = function() {
			callback(err);
		};

		socket.on('error', onerror);
		socket.on('connect', function() {
			socket.removeListener('error', onerror);
			callback(null, socket);
		});
	};

	connect(function(err, socket) {
		if (err) return fork();
		callback(null, socket);
	});
};

var pool = {};
var listen = function(port) {
	var that = common.createEmitter();
	var app = root();
	var id = process.pid.toString(16)+Math.random().toString(16).substr(2);
	var heartbeat;

	var onmonitor = common.future();
	var monitor = function(message) {
		onmonitor.get(function(err, daemon) {
			if (!daemon || !daemon.writable) return;
			daemon.write(JSON.stringify(message)+'\n');
		});
	};

	startMonitor(onmonitor.put);

	var cache = {};
	var own = new Bucket(id);
	var buckets = {me:own};
	var proxy = function(buck) {
		buck.on('push', function(key, values) {
			cache = {};
			values.forEach(function(val) {
				that.emit('push', key, val);
			});
		});
		buck.on('pop', function(key, values) {
			values.forEach(function(val) {
				that.emit('pop', key, val);
			});
		});
	};
	var bucket = function(uri) {
		var buck = buckets[uri];

		if (buck) return buck;

		monitor({up:uri});
		buck = buckets[uri] = new Bucket(uri);
		buck.on('destroy', function() {
			cache = {};
			delete buckets[uri];
			monitor({down:uri});
		});

		proxy(buck);
		return buck;
	};
	var gc = function() {
		remote(function(buck) {
			request({
				uri: buck.uri+'/ping',
				json: true,
				timeout: PING_TIMEOUT
			}, onresponse(buck));
		});

		clearTimeout(heartbeat);
		heartbeat = setTimeout(gc, HEARTBEAT);
	};
	var onresponse = function(buck) {
		return function(err, res, body) {
			if (!err && res.statusCode === 200 && body.ack) return;
			buck.destroy();
		};
	};
	var remote = function(fn) {
		Object.keys(buckets).forEach(function(uri) {
			if (uri === 'me') return;
			fn(buckets[uri]);
		});
	};

	proxy(own);
	own.on('push', function(key, values) {
		cache = {};
		remote(function(buck) {
			request.post({
				uri: buck.uri+'/data/'+key,
				headers: {'x-bucket': buck.uri},
				json: true,
				body: values
			}, onresponse(buck));
		});
	});

	app.use(root.json);

	app.get('/'+id, function(req, res) {
		res.json(own);
	});
	app.get('/'+id+'/ping', function(req, res) {
		res.json({ack:true});
	});
	app.post('/'+id+'/gc', function(req, res) {
		gc();
		res.json({ack:true});
	});
	app.post('/'+id+'/data/:key', function(req, res) {
		var buck = bucket(req.headers['x-bucket'] || own.uri);

		buck.push(req.params.key, req.json);
		res.json({ack:true});
	});

	app.listen(0, function() {
		own.uri = 'http://'+ME+':'+app.address().port+'/'+id;
		gc();

		announce(own.uri, function(uri) {
			request({
				uri: uri,
				json: true
			}, function(err, res, body) {
				if (err || res.statusCode !== 200) return;

				bucket(uri).pushAll(body);
				gc();
			});
		});
	});

	that.address = ME;
	that.push = function(key, val) {
		own.push(key, val);
	};
	that.get = function(key) {
		if (cache[key]) return cache[key];

		var list = cache[key] = [];

		Object.keys(buckets).forEach(function(uri) {
			Array.prototype.push.apply(list, buckets[uri].get(key));
		});

		return list;
	};
	that.all = function() {
		if (cache._all) return cache._all;

		var all = cache._all = {};

		Object.keys(buckets).forEach(function(uri) {
			var bucket = buckets[uri];

			bucket.keys().forEach(function(key) {
				Array.prototype.push.apply(all[key] = all[key] || [], bucket.get(key));
			});
		});

		return all;
	};

	return that;
};
var proxy = function(port) {
	var shared = pool[port] || (pool[port] = listen(port));
	var that = common.createEmitter();

	process.nextTick(function() {
		var all = shared.all();

		Object.keys(all).forEach(function(key) {
			all[key].forEach(function(val) {
				that.emit('push', key, val);
			});
		});

		shared.on('push', function(key, val) {
			that.emit('push', key, val);
		});
		shared.on('pop', function(key, val) {
			that.emit('pop', key, val);
		});
	});

	PROXY.forEach(function(method) {
		that[method] = shared[method];
	});

	return that;
};

module.exports = proxy;<commit_msg>fixed bug in onerror not defining err<commit_after>var root = require('root');
var request = require('request');
var common = require('common');
var immortal = require('immortal');
var announce = require('./announce');
var net = require('net');

var Bucket = common.emitter(function(uri) {
	this.uri = uri;
	this.all = {};
});

Bucket.prototype.keys = function() {
	return Object.keys(this.all);
};
Bucket.prototype.pushAll = function(vals) {
	var self = this;

	Object.keys(vals).forEach(function(key) {
		self.push(key, vals[key]);
	});
};
Bucket.prototype.push = function(key, val) {
	var list = this.all[key] = this.get(key);

	val = Array.isArray(val) ? val : [val];
	list.push.apply(list, val);
	this.emit('push', key, val);
};
Bucket.prototype.pop = function(key) {
	var list = this.all[key];

	if (!list) return;
	delete this.all[key];
	this.emit('pop', key, list);
};
Bucket.prototype.get = function(key) {
	return this.all[key] || [];
};
Bucket.prototype.destroy = function() {
	this.emit('destroy');
	this.keys().forEach(this.pop.bind(this));
};
Bucket.prototype.toJSON = function() {
	return this.all;
};

var PROXY = 'address get all push'.split(' ');
var PING_TIMEOUT = 10*0000;
var HEARTBEAT = 2*60*1000;
var ME = function() {
	var nets = require('os').networkInterfaces();

	for (var i in nets) {
		var candidate = nets[i].filter(function(item) {
			return item.family === 'IPv4' && !item.internal;
		})[0];

		if (candidate) {
			return candidate.address;
		}
	}

	return '127.0.0.1';
}();

var startMonitor = function(callback) {
	var retry = function() {
		connect(function(err, socket) {
			if (err) return setTimeout(retry, 100);
			callback(null, socket);
		});
	};
	var fork = function() {
		immortal.start(__dirname+'/monitor.js', {
			strategy: 'unattached',
			auto:false,
			monitor:null
		}, function() {
			retry();
		});
	};
	var connect = function(callback) {
		var socket = net.connect(67567, '127.0.0.1');
		var onerror = function(err) {
			callback(err);
		};

		socket.on('error', onerror);
		socket.on('connect', function() {
			socket.removeListener('error', onerror);
			callback(null, socket);
		});
	};

	connect(function(err, socket) {
		if (err) return fork();
		callback(null, socket);
	});
};

var pool = {};
var listen = function(port) {
	var that = common.createEmitter();
	var app = root();
	var id = process.pid.toString(16)+Math.random().toString(16).substr(2);
	var heartbeat;

	var onmonitor = common.future();
	var monitor = function(message) {
		onmonitor.get(function(err, daemon) {
			if (!daemon || !daemon.writable) return;
			daemon.write(JSON.stringify(message)+'\n');
		});
	};

	startMonitor(onmonitor.put);

	var cache = {};
	var own = new Bucket(id);
	var buckets = {me:own};
	var proxy = function(buck) {
		buck.on('push', function(key, values) {
			cache = {};
			values.forEach(function(val) {
				that.emit('push', key, val);
			});
		});
		buck.on('pop', function(key, values) {
			values.forEach(function(val) {
				that.emit('pop', key, val);
			});
		});
	};
	var bucket = function(uri) {
		var buck = buckets[uri];

		if (buck) return buck;

		monitor({up:uri});
		buck = buckets[uri] = new Bucket(uri);
		buck.on('destroy', function() {
			cache = {};
			delete buckets[uri];
			monitor({down:uri});
		});

		proxy(buck);
		return buck;
	};
	var gc = function() {
		remote(function(buck) {
			request({
				uri: buck.uri+'/ping',
				json: true,
				timeout: PING_TIMEOUT
			}, onresponse(buck));
		});

		clearTimeout(heartbeat);
		heartbeat = setTimeout(gc, HEARTBEAT);
	};
	var onresponse = function(buck) {
		return function(err, res, body) {
			if (!err && res.statusCode === 200 && body.ack) return;
			buck.destroy();
		};
	};
	var remote = function(fn) {
		Object.keys(buckets).forEach(function(uri) {
			if (uri === 'me') return;
			fn(buckets[uri]);
		});
	};

	proxy(own);
	own.on('push', function(key, values) {
		cache = {};
		remote(function(buck) {
			request.post({
				uri: buck.uri+'/data/'+key,
				headers: {'x-bucket': buck.uri},
				json: true,
				body: values
			}, onresponse(buck));
		});
	});

	app.use(root.json);

	app.get('/'+id, function(req, res) {
		res.json(own);
	});
	app.get('/'+id+'/ping', function(req, res) {
		res.json({ack:true});
	});
	app.post('/'+id+'/gc', function(req, res) {
		gc();
		res.json({ack:true});
	});
	app.post('/'+id+'/data/:key', function(req, res) {
		var buck = bucket(req.headers['x-bucket'] || own.uri);

		buck.push(req.params.key, req.json);
		res.json({ack:true});
	});

	app.listen(0, function() {
		own.uri = 'http://'+ME+':'+app.address().port+'/'+id;
		gc();

		announce(own.uri, function(uri) {
			request({
				uri: uri,
				json: true
			}, function(err, res, body) {
				if (err || res.statusCode !== 200) return;

				bucket(uri).pushAll(body);
				gc();
			});
		});
	});

	that.address = ME;
	that.push = function(key, val) {
		own.push(key, val);
	};
	that.get = function(key) {
		if (cache[key]) return cache[key];

		var list = cache[key] = [];

		Object.keys(buckets).forEach(function(uri) {
			Array.prototype.push.apply(list, buckets[uri].get(key));
		});

		return list;
	};
	that.all = function() {
		if (cache._all) return cache._all;

		var all = cache._all = {};

		Object.keys(buckets).forEach(function(uri) {
			var bucket = buckets[uri];

			bucket.keys().forEach(function(key) {
				Array.prototype.push.apply(all[key] = all[key] || [], bucket.get(key));
			});
		});

		return all;
	};

	return that;
};
var proxy = function(port) {
	var shared = pool[port] || (pool[port] = listen(port));
	var that = common.createEmitter();

	process.nextTick(function() {
		var all = shared.all();

		Object.keys(all).forEach(function(key) {
			all[key].forEach(function(val) {
				that.emit('push', key, val);
			});
		});

		shared.on('push', function(key, val) {
			that.emit('push', key, val);
		});
		shared.on('pop', function(key, val) {
			that.emit('pop', key, val);
		});
	});

	PROXY.forEach(function(method) {
		that[method] = shared[method];
	});

	return that;
};

module.exports = proxy;<|endoftext|>


<commit_before>/* vim: set filetype=javascript shiftwidth=4 tabstop=4 expandtab: */
/*
 * @repository
 *    https://github.com/saneyuki/observer-js
 * @license
 *    BSD 2-Clause License.
 *
 * Copyright (c) 2014,  Tetsuharu OHZEKI <saneyuki.snyk@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice, this
 *    list of conditions and the following disclaimer in the documentation and/or
 *    other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

// FIXME: This tests should be async.

var ObserverSubject = window.ObserverSubject;
var gSubject = null;
var gObserver = null;

var baseSetup = function () {
    gSubject = new ObserverSubject();
    gObserver = {
        handleMessage: function () {
        }
    };
};

var baseTeardown = function () {
    gSubject = null;
    gObserver = null;
};

module("ObserverSubject.add()", {
    setup: baseSetup,
    teardown: baseTeardown
});

test("valid case", function(){
    gObserver.handleMessage = function () {
        ok(true, "test1");
    };

    gSubject.add("test", gObserver);
    gSubject.notify("test", null);
});
test("if the arg1 is invalid", function(){
    throws(function () {
        gSubject.add();
    },
    Error,
    "the arg1 is nothing.");

    throws(function () {
        gSubject.add(null, gObserver);
    },
    Error,
    "the arg1 is `null`.");

    throws(function () {
        gSubject.add(undefined, gObserver);
    },
    Error,
    "the arg1 is `undefined`.");
});
test("if the arg2 is invalid", function(){
    throws(function () {
        gSubject.add("test");
    },
    Error,
    "the arg2 is nothing.");

    throws(function () {
        gSubject.add("test", null);
    },
    Error,
    "the arg2 is `null`.");

    throws(function () {
        gSubject.add("test", undefined);
    },
    Error,
    "the arg2 is `undefined`.");

    throws(function () {
        gSubject.add("test", Object.create(null));
    },
    Error,
    "the arg2 doesn't have `handleMessage` method.");

    throws(function () {
        gSubject.add("test", {
            handleMessage: "test"
        });
    },
    Error,
    "the type of arg2's `handleMessage` method is not a function.");
});

module("ObserverSubject.notify()", {
    setup: baseSetup,
    teardown: baseTeardown
});
test("valid case", function(){
    var subject = new ObserverSubject();

    subject.add("test1", {
        handleMessage: function (aTopic, aData) {
            strictEqual(aTopic, "test1", "1: valid topic");
            strictEqual(aData, "hoge", "1: valid data");
        }
    });
    subject.notify("test1", "hoge");

    subject.add("test2", {
        handleMessage: function (aTopic, aData) {
            strictEqual(aTopic, "test2", "2: valid topic");
            strictEqual(aData, null, "2: valid data");
        }
    });
    subject.notify("test2", null);

    subject.add("test3", {
        handleMessage: function (aTopic, aData) {
            strictEqual(aTopic, "test3", "3: valid topic");
            strictEqual(aData, undefined, "3: valid data");
        }
    });
    subject.notify("test3", undefined);
});

module("ObserverSubject.remove()", {
    setup: baseSetup,
    teardown: baseTeardown
});
test("valid case", function(){
    // this will be false if `gObserver.handleMessage()` called.
    var flag = true;
    gObserver.handleMessage = function () {
        flag = false;
    };

    // add gObserver once.
    gSubject.add("test", gObserver);
    // remove gObserver immidiately.
    gSubject.remove("test", gObserver);

    // this shouldn't call `gObserver.handleMessage()`.
    gSubject.notify("test", null);
    strictEqual(flag, true, "should not call `gObserver.handleMessage()` after remove it");
});
test("if the arg1 is invalid", function(){
    throws(function () {
        gSubject.remove();
    },
    Error,
    "the arg1 is nothing.");

    throws(function () {
        gSubject.remove(null, gObserver);
    },
    Error,
    "the arg1 is `null`.");

    throws(function () {
        gSubject.remove(undefined, gObserver);
    },
    Error,
    "the arg1 is `undefined`.");
});
test("if the arg2 is invalid", function(){
    throws(function () {
        gSubject.remove("test");
    },
    Error,
    "the arg2 is nothing.");

    throws(function () {
        gSubject.remove("test", null);
    },
    Error,
    "the arg2 is `null`.");

    throws(function () {
        gSubject.remove("test", undefined);
    },
    Error,
    "the arg2 is `undefined`.");
});

module("ObserverSubject.removAll()", {
    setup: baseSetup,
    teardown: baseTeardown
});
test("valid case", function() {
    var TOPIC = "test";
    var subject = new ObserverSubject();

    var flag1 = true;
    var t1 = {
        handleMessage: function () {
            flag1 = false;
        },
    };
    var flag2 = true;
    var t2 = {
        handleMessage: function () {
            flag2 = false;
        },
    };

    subject.add(TOPIC, t1);
    subject.add(TOPIC, t2);

    subject.removeAll(TOPIC);

    subject.notify(TOPIC, null);

    strictEqual(flag1, true, "shouldn't broadcast the massage: 1.");
    strictEqual(flag2, true, "shouldn't broadcast the massage: 2.");
});
test("if the arg is invalid", function(){
    throws(function () {
        gSubject.removeAll();
    },
    Error,
    "the arg is nothing.");

    throws(function () {
        gSubject.removeAll(null);
    },
    Error,
    "the arg is `null`.");

    throws(function () {
        gSubject.removeAll(undefined);
    },
    Error,
    "the arg is `undefined`.");
});

module("Subject Independency", {
    setup: function(){},
    teardown: function(){}
});
test("Assert a subject independency", function() {
    var subject1 = new ObserverSubject();
    var subject2 = new ObserverSubject();

    var flag =true;
    subject1.add("test", {
        handleMessage: function (aData) {
            flag = false;
        }
    });

    subject2.notify("test", null);
    strictEqual(flag, true, "shouldn't propagate messages to other subjects.");
});
<commit_msg>Add the testcase for "ObserverSubject.remove()" removes 1 robserver when multiple observers are registered.<commit_after>/* vim: set filetype=javascript shiftwidth=4 tabstop=4 expandtab: */
/*
 * @repository
 *    https://github.com/saneyuki/observer-js
 * @license
 *    BSD 2-Clause License.
 *
 * Copyright (c) 2014,  Tetsuharu OHZEKI <saneyuki.snyk@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice, this
 *    list of conditions and the following disclaimer in the documentation and/or
 *    other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

// FIXME: This tests should be async.

var ObserverSubject = window.ObserverSubject;
var gSubject = null;
var gObserver = null;

var baseSetup = function () {
    gSubject = new ObserverSubject();
    gObserver = {
        handleMessage: function () {
        }
    };
};

var baseTeardown = function () {
    gSubject = null;
    gObserver = null;
};

module("ObserverSubject.add()", {
    setup: baseSetup,
    teardown: baseTeardown
});

test("valid case", function(){
    gObserver.handleMessage = function () {
        ok(true, "test1");
    };

    gSubject.add("test", gObserver);
    gSubject.notify("test", null);
});
test("if the arg1 is invalid", function(){
    throws(function () {
        gSubject.add();
    },
    Error,
    "the arg1 is nothing.");

    throws(function () {
        gSubject.add(null, gObserver);
    },
    Error,
    "the arg1 is `null`.");

    throws(function () {
        gSubject.add(undefined, gObserver);
    },
    Error,
    "the arg1 is `undefined`.");
});
test("if the arg2 is invalid", function(){
    throws(function () {
        gSubject.add("test");
    },
    Error,
    "the arg2 is nothing.");

    throws(function () {
        gSubject.add("test", null);
    },
    Error,
    "the arg2 is `null`.");

    throws(function () {
        gSubject.add("test", undefined);
    },
    Error,
    "the arg2 is `undefined`.");

    throws(function () {
        gSubject.add("test", Object.create(null));
    },
    Error,
    "the arg2 doesn't have `handleMessage` method.");

    throws(function () {
        gSubject.add("test", {
            handleMessage: "test"
        });
    },
    Error,
    "the type of arg2's `handleMessage` method is not a function.");
});

module("ObserverSubject.notify()", {
    setup: baseSetup,
    teardown: baseTeardown
});
test("valid case", function(){
    var subject = new ObserverSubject();

    subject.add("test1", {
        handleMessage: function (aTopic, aData) {
            strictEqual(aTopic, "test1", "1: valid topic");
            strictEqual(aData, "hoge", "1: valid data");
        }
    });
    subject.notify("test1", "hoge");

    subject.add("test2", {
        handleMessage: function (aTopic, aData) {
            strictEqual(aTopic, "test2", "2: valid topic");
            strictEqual(aData, null, "2: valid data");
        }
    });
    subject.notify("test2", null);

    subject.add("test3", {
        handleMessage: function (aTopic, aData) {
            strictEqual(aTopic, "test3", "3: valid topic");
            strictEqual(aData, undefined, "3: valid data");
        }
    });
    subject.notify("test3", undefined);
});

module("ObserverSubject.remove()", {
    setup: baseSetup,
    teardown: baseTeardown
});
test("valid case: unregister the single observer.", function(){
    // this will be false if `gObserver.handleMessage()` called.
    var flag = true;
    gObserver.handleMessage = function () {
        flag = false;
    };

    // add gObserver once.
    gSubject.add("test", gObserver);
    // remove gObserver immidiately.
    gSubject.remove("test", gObserver);

    // this shouldn't call `gObserver.handleMessage()`.
    gSubject.notify("test", null);
    strictEqual(flag, true, "should not call `gObserver.handleMessage()` after remove it");
});
test("valid case: unregister the multiple observer.", function(){
    // flags will be false if `gObserver.handleMessage()` called.
    var isCalled1 = true;
    var o1 = {
        handleMessage: function () {
            isCalled1 = false;
        }
    };

    var isCalled2 = true;
    var o2 = {
        handleMessage: function () {
            isCalled2 = false;
        }
    };

    var isCalled3 = true;
    var o3 = {
        handleMessage: function () {
            isCalled3 = false;
        }
    };

    gSubject.add("test", o1);
    gSubject.add("test", o2);
    gSubject.add("test", o3);

    gSubject.remove("test", o2);
    gSubject.notify("test", null);

    strictEqual(isCalled1, false, "should call 'o1.handleMessage()'.");
    strictEqual(isCalled2, true, "should not call 'o2.handleMessage()' after remove it");
    strictEqual(isCalled3, false, "should call 'o3.handleMessage()'.");
});
test("if the arg1 is invalid", function(){
    throws(function () {
        gSubject.remove();
    },
    Error,
    "the arg1 is nothing.");

    throws(function () {
        gSubject.remove(null, gObserver);
    },
    Error,
    "the arg1 is `null`.");

    throws(function () {
        gSubject.remove(undefined, gObserver);
    },
    Error,
    "the arg1 is `undefined`.");
});
test("if the arg2 is invalid", function(){
    throws(function () {
        gSubject.remove("test");
    },
    Error,
    "the arg2 is nothing.");

    throws(function () {
        gSubject.remove("test", null);
    },
    Error,
    "the arg2 is `null`.");

    throws(function () {
        gSubject.remove("test", undefined);
    },
    Error,
    "the arg2 is `undefined`.");
});

module("ObserverSubject.removAll()", {
    setup: baseSetup,
    teardown: baseTeardown
});
test("valid case", function() {
    var TOPIC = "test";
    var subject = new ObserverSubject();

    var flag1 = true;
    var t1 = {
        handleMessage: function () {
            flag1 = false;
        },
    };
    var flag2 = true;
    var t2 = {
        handleMessage: function () {
            flag2 = false;
        },
    };

    subject.add(TOPIC, t1);
    subject.add(TOPIC, t2);

    subject.removeAll(TOPIC);

    subject.notify(TOPIC, null);

    strictEqual(flag1, true, "shouldn't broadcast the massage: 1.");
    strictEqual(flag2, true, "shouldn't broadcast the massage: 2.");
});
test("if the arg is invalid", function(){
    throws(function () {
        gSubject.removeAll();
    },
    Error,
    "the arg is nothing.");

    throws(function () {
        gSubject.removeAll(null);
    },
    Error,
    "the arg is `null`.");

    throws(function () {
        gSubject.removeAll(undefined);
    },
    Error,
    "the arg is `undefined`.");
});

module("Subject Independency", {
    setup: function(){},
    teardown: function(){}
});
test("Assert a subject independency", function() {
    var subject1 = new ObserverSubject();
    var subject2 = new ObserverSubject();

    var flag =true;
    subject1.add("test", {
        handleMessage: function (aData) {
            flag = false;
        }
    });

    subject2.notify("test", null);
    strictEqual(flag, true, "shouldn't propagate messages to other subjects.");
});
<|endoftext|>


<commit_before>'use strict'

import Decoder from '../lib/broadway/Decoder.js'
import Texture from './Texture'

export default class H264ViewState {

  /**
   *
   * @param {WebGLRenderingContext} gl
   * @param {Size} size
   * @returns {H264ViewState}
   */
  static create (gl, size) {
    const decoder = new Decoder()

    const YTexture = new Texture(gl, size)
    const UTexture = new Texture(gl, size.getHalfSize())
    const VTexture = new Texture(gl, size.getHalfSize())

    const h264ViewState = new H264ViewState(decoder, YTexture, UTexture, VTexture, size)
    decoder.onPictureDecoded = h264ViewState._onPictureDecoded

    return h264ViewState
  }

  /**
   *
   * @param decoder
   * @param {Texture} YTexture
   * @param {Texture}UTexture
   * @param {Texture}VTexture
   * @param {Size} size
   */
  constructor (decoder, YTexture, UTexture, VTexture, size) {
    this.decoder = decoder
    this.YTexture = YTexture
    this.UTexture = UTexture
    this.VTexture = VTexture
    this.size = size
    // TODO We might also want to introduce blob images (ie png) that can be rendered either directly without the need
    // of gl or decoders (functional similar to hw planes) or the RGBASurfaceShader can be used.
    this.type = 'h264'
  }

  /**
   *
   * @param {Uint8Array} h264Nal
   */
  decode (h264Nal) {
    this.decoder.decode(h264Nal)
  }

  _onPictureDecoded (buffer, width, height) {
    if (!buffer) { return }

    const lumaSize = width * height
    const chromaSize = lumaSize >> 2

    this.YTexture.fill(buffer.subarray(0, lumaSize))
    this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize))
    this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize))
  }

  // TODO handle state destruction
  // TODO optimize texture uploading by using surface/view damage info
}
<commit_msg>use static create method to instantiate textures<commit_after>'use strict'

import Decoder from '../lib/broadway/Decoder.js'
import Texture from './Texture'

export default class H264ViewState {

  /**
   *
   * @param {WebGLRenderingContext} gl
   * @param {Size} size
   * @returns {H264ViewState}
   */
  static create (gl, size) {
    const decoder = new Decoder()

    const YTexture = Texture.create(gl, size, gl.LUMINANCE)
    const UTexture = Texture.create(gl, size.getHalfSize(), gl.LUMINANCE)
    const VTexture = Texture.create(gl, size.getHalfSize(), gl.LUMINANCE)

    const h264ViewState = new H264ViewState(decoder, YTexture, UTexture, VTexture, size)
    decoder.onPictureDecoded = h264ViewState._onPictureDecoded.bind(h264ViewState)

    return h264ViewState
  }

  /**
   *
   * @param decoder
   * @param {Texture} YTexture
   * @param {Texture}UTexture
   * @param {Texture}VTexture
   * @param {Size} size
   */
  constructor (decoder, YTexture, UTexture, VTexture, size) {
    this.decoder = decoder
    this.YTexture = YTexture
    this.UTexture = UTexture
    this.VTexture = VTexture
    this.size = size
    // TODO We might also want to introduce blob images (ie png) that can be rendered either directly without the need
    // of gl or decoders (functional similar to hw planes) or the RGBASurfaceShader can be used.
    this.type = 'h264'
  }

  /**
   *
   * @param {Uint8Array} h264Nal
   */
  decode (h264Nal) {
    this.decoder.decode(h264Nal)
  }

  _onPictureDecoded (buffer, width, height) {
    if (!buffer) { return }

    const lumaSize = width * height
    const chromaSize = lumaSize >> 2

    this.YTexture.fill(buffer.subarray(0, lumaSize))
    this.UTexture.fill(buffer.subarray(lumaSize, lumaSize + chromaSize))
    this.VTexture.fill(buffer.subarray(lumaSize + chromaSize, lumaSize + 2 * chromaSize))
  }

  onDecode () {}

  // TODO handle state destruction
  // TODO optimize texture uploading by using surface/view damage info
}
<|endoftext|>


<commit_before><commit_msg>started test file<commit_after>import asserts from 'asserts';<|endoftext|>


<commit_before>var assert = require('assert'),
    xmlparser = require('./../index.js'),
    express = require('express'),
    request = require('supertest'),
    itemList = {list: {item: ['item1', 'item2', 'item3']}},
    itemsXML = '<list><item>item1</item><item>item2</item><item>item3</item></list>';

describe('XmlParserMiddleware', function () {

    describe('#testMime', function () {

        var regexp = xmlparser.regexp;

        it('should detect common XML mime-types', function () {

            assert.equal(true, regexp.test('text/xml'));
            assert.equal(true, regexp.test('application/xml'));
            assert.equal(true, regexp.test('application/rss+xml'));
            assert.equal(true, regexp.test('application/atom+xml'));
            assert.equal(true, regexp.test('application/vnd.google-earth.kml+xml'));
            assert.equal(true, regexp.test('application/xhtml+xml'));

        });

        it('should not interfere with other body parsers', function () {

            assert.equal(false, regexp.test('application/json'));
            assert.equal(false, regexp.test('application/x-www-form-urlencoded'));
            assert.equal(false, regexp.test('multipart/form-data'));

        });

    });

    describe('#testMiddleware', function () {

        var app = express();

        app.use(xmlparser());
        app.post('/', function(req, res) {
            res.json(req.body);
        });

        it('should throw 411 on null request', function (done) {
            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .expect(411, done)
            ;
        });

        it('should throw 411 on empty request body', function (done) {
            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .send('   ')
              .expect(411, done)
            ;
        });

        it('should parse xml body', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'application/vendor-spec+xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual(itemList, res.body);
              });
        });

        it('should throw 400 on invalid xml body', function (done) {

            request(app)
              .post('/')
              .set('Content-Type', 'application/vendor-spec+xml')
              .send('<xml>this is invalid')
              .expect(400, done)
            ;
        });

    });

    describe('#testOtherBodyParser', function () {

        var app = express();
        app.use(function fakeMiddleware(req, res, next) {
          // simulate previous bodyparser by setting req._body = true
          req._body = true;
          req.body = 'fake data';
          next();
        });
        app.use(xmlparser());
        app.post('/', function(req, res) {
          res.json(req.body);
        });

        it('should not parse body if other bodyparser ran before', function (done) {
          request(app)
            .post('/')
            .set('Content-Type', 'application/xml')
            .send(itemsXML)
            .expect(200, '"fake data"', done);
        });

    });

    describe('#testCustomRegExp', function () {

        // get a fresh export instead of a reference to `xmlbodyparser`
        delete require.cache[require.resolve('../index.js')];

        var middleware = require('../index.js');
        var app = express();

        middleware.regexp = /custom\/mime/i;

        app.use(middleware);

        app.post('/', function(req, res) {
            res.json(req.body);
        });

        it('should permit overloading mime-type regular expression', function () {

            assert.notEqual(middleware, xmlparser.regexp);
            assert.equal(true, middleware.regexp.test('custom/mime'));
            assert.equal(false, middleware.regexp.test('application/xml'));

        });

        it('should ignore non-matching content-types', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual({}, res.body);
              });

        });

        it('should parse matching content-types', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'custom/mime')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual(itemList, res.body);
              });

        });

    });

    describe('#testRouteMiddleware', function () {

        var app = express();

        app.post('/', function(req, res) {
            res.json(req.body);
        });
        app.post('/xml', xmlparser(), function(req, res) {
            res.json(req.body);
        });

        it('should not act as an app middleware', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual({}, res.body);
              });

        });

        it('should parse route xml request', function () {

            request(app)
              .post('/xml')
              .set('Content-Type', 'application/xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual(itemList, res.body);
              });

        });

    });

});

<commit_msg>test: add cases for get requests and missing content-type header<commit_after>var assert = require('assert'),
    xmlparser = require('./../index.js'),
    express = require('express'),
    request = require('supertest'),
    itemList = {list: {item: ['item1', 'item2', 'item3']}},
    itemsXML = '<list><item>item1</item><item>item2</item><item>item3</item></list>';

describe('XmlParserMiddleware', function () {

    describe('#testMime', function () {

        var regexp = xmlparser.regexp;

        it('should detect common XML mime-types', function () {

            assert.equal(true, regexp.test('text/xml'));
            assert.equal(true, regexp.test('application/xml'));
            assert.equal(true, regexp.test('application/rss+xml'));
            assert.equal(true, regexp.test('application/atom+xml'));
            assert.equal(true, regexp.test('application/vnd.google-earth.kml+xml'));
            assert.equal(true, regexp.test('application/xhtml+xml'));

        });

        it('should not interfere with other body parsers', function () {

            assert.equal(false, regexp.test('application/json'));
            assert.equal(false, regexp.test('application/x-www-form-urlencoded'));
            assert.equal(false, regexp.test('multipart/form-data'));

        });

    });

    describe('#testMiddleware', function () {

        var app = express();

        app.use(xmlparser());
        app.get('/', function (req, res) {
            res.json(req.body);
        });
        app.post('/', function(req, res) {
            res.json(req.body);
        });

        it('should not run if there is no request-body', function (done) {
          request(app)
            .get('/')
            .expect(200, '{}', done);
        });

        it('should not run if there no content-type header', function (done) {
          request(app)
            .post('/')
            .send(itemsXML)
            .expect(200, '{}', done);
        });

        it('should throw 411 on null request', function (done) {
            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .expect(411, done)
            ;
        });

        it('should throw 411 on empty request body', function (done) {
            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .send('   ')
              .expect(411, done)
            ;
        });

        it('should parse xml body', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'application/vendor-spec+xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual(itemList, res.body);
              });
        });

        it('should throw 400 on invalid xml body', function (done) {

            request(app)
              .post('/')
              .set('Content-Type', 'application/vendor-spec+xml')
              .send('<xml>this is invalid')
              .expect(400, done)
            ;
        });

    });

    describe('#testOtherBodyParser', function () {

        var app = express();
        app.use(function fakeMiddleware(req, res, next) {
          // simulate previous bodyparser by setting req._body = true
          req._body = true;
          req.body = 'fake data';
          next();
        });
        app.use(xmlparser());
        app.post('/', function(req, res) {
          res.json(req.body);
        });

        it('should not parse body if other bodyparser ran before', function (done) {
          request(app)
            .post('/')
            .set('Content-Type', 'application/xml')
            .send(itemsXML)
            .expect(200, '"fake data"', done);
        });

    });

    describe('#testCustomRegExp', function () {

        // get a fresh export instead of a reference to `xmlbodyparser`
        delete require.cache[require.resolve('../index.js')];

        var middleware = require('../index.js');
        var app = express();

        middleware.regexp = /custom\/mime/i;

        app.use(middleware);

        app.post('/', function(req, res) {
            res.json(req.body);
        });

        it('should permit overloading mime-type regular expression', function () {

            assert.notEqual(middleware, xmlparser.regexp);
            assert.equal(true, middleware.regexp.test('custom/mime'));
            assert.equal(false, middleware.regexp.test('application/xml'));

        });

        it('should ignore non-matching content-types', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual({}, res.body);
              });

        });

        it('should parse matching content-types', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'custom/mime')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual(itemList, res.body);
              });

        });

    });

    describe('#testRouteMiddleware', function () {

        var app = express();

        app.post('/', function(req, res) {
            res.json(req.body);
        });
        app.post('/xml', xmlparser(), function(req, res) {
            res.json(req.body);
        });

        it('should not act as an app middleware', function () {

            request(app)
              .post('/')
              .set('Content-Type', 'application/xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual({}, res.body);
              });

        });

        it('should parse route xml request', function () {

            request(app)
              .post('/xml')
              .set('Content-Type', 'application/xml')
              .send(itemsXML)
              .expect(200)
              .end(function(err, res) {
                  if (err) throw err;
                  assert.deepEqual(itemList, res.body);
              });

        });

    });

});

<|endoftext|>