<commit_before>describe('ax5.util.date TEST', function () {
    /* ax5.util.date */
    //Usage 01
    it('ax5.util.date("2013-01-01")', function () {
        var date = new Date(2013, 0, 1);
        date.setHours(12);
        date.setMinutes(0);
        should.deepEqual(ax5.util.date('2013-01-01'), date);
    });

    //Usage 02
    it('ax5.util.date((new Date()) , {add:{d:10} , return:"yyyy/MM/dd"})', function () {
        var date = new Date();
        date.setDate(date.getDate() + 10);
        var str = date.getFullYear() + "/" + ax5.util.setDigit(date.getMonth() + 1, 2) + "/" + ax5.util.setDigit(date.getDate(), 2);

        should.deepEqual(ax5.util.date((new Date()), {add: {d: 10}, return: 'yyyy/MM/dd'}), str);
    });

    //Usage 03
    it('ax5.util.date("1919-03-01", {add:{d:10}, return:"yyyy/MM/dd hh:mm:ss"})', function () {
        should.deepEqual(ax5.util.date("1919-03-01", {add: {d: 10}, return: "yyyy/MM/dd hh:mm:ss"}), '1919/03/11 12:00:00');
    });

    //Usage 04
    it('ax5.util.date((new Date()) , {set:"firstDayOfMonth", return:"yyyy/MM/dd"})', function () {
        var date = new Date();
        var str = date.getFullYear() + "/" + ax5.util.setDigit(date.getMonth() + 1, 2) + "/01";
        should.deepEqual(ax5.util.date((new Date()), {set: "firstDayOfMonth", return: 'yyyy/MM/dd'}), str);
    });

    //Usage 05
    it('ax5.util.date((new Date()) , {set:"lastDayOfMonth", return:"yyyy/MM/dd"})', function () {
        var date = new Date();
        var str = date.getFullYear() + "/" + ax5.util.setDigit(date.getMonth() + 1, 2) + "/" + ax5.util.daysOfMonth(date.getFullYear(), date.getMonth());
        should.deepEqual(ax5.util.date((new Date()), {set: "lastDayOfMonth", return: 'yyyy/MM/dd'}), str);
    });

    //Usage 06
    it('ax5.util.date("20170411103317") [string.length == 14]', function () {
        var date = new Date(2017, 3, 11);
        date.setHours(10);
        date.setMinutes(33);
        date.setSeconds(17);
        should.deepEqual(ax5.util.date("20170411103317"), date);
    });

    //Usage 07
    it('ax5.util.date("201704") [string.length > 7]', function () {
        var date = new Date(2017, 3, 12);
        date.setHours(12);
        should.deepEqual(ax5.util.date("20170412"), date);
    });

    //Usage 08
    it('ax5.util.date("201704") [string.length > 4]', function () {
        var date = new Date(2017, 3);
        date.setHours(12);
        should.deepEqual(ax5.util.date("201704"), date);
    });

    //Usage 09
    it('ax5.util.date("2017") [string.length > 2]', function () {
        var date = new Date(2017, 0);
        date.setHours(12);
        should.deepEqual(ax5.util.date("2017"), date);
    });

    //Usage 10
    it('ax5.util.date("17") [string.length <= 2]', function () {
        var date = new Date();
        should.deepEqual(ax5.util.date("17"), date);
    });

    //Usage 11
    it('ax5.util.date(date, {return: "yyyy-MM-dd"})', function () {
        var date = new Date(2017, 3, 16);
        should.deepEqual(ax5.util.date(date, {return: "yyyy-MM-dd"}), "2017-04-16");
    });

    //Usage 12
    it('ax5.util.date(date, {return: "yyyy-MM-dd hh:mm:ss"})', function () {
        var date = new Date(2017, 3, 16, 12, 30, 15);
        should.deepEqual(ax5.util.date(date, {return: "yyyy-MM-dd hh:mm:ss"}), "2017-04-16 12:30:15");
    });

    /* end ax5.util.date */
});

describe('ax5.util.dday TEST', function () {
    /* ax5.util.dday*/
    //Usage 01
    it('ax5.util.dday(new Date())', function () {
        should.deepEqual(ax5.util.dday(new Date()), 0);
    });

    //Usage 02
    it('ax5.util.dday("2016-01-29" , {today:"2016-01-28"})', function () {
        should.deepEqual(ax5.util.dday("2016-01-29", {today: "2016-01-28"}), 1);
    });

    //Usage 03
    it('ax5.util.dday("1977-03-29" , {today:"2016-01-28" , age:true})', function () {
        should.deepEqual(ax5.util.dday("1977-03-29", {today: "2016-01-28", age: true}), 39);
    });
    /* end ax5.util.dday*/
});

describe('ax5.util.weeksOfMonth TEST', function () {
    /* ax5.util.weeksOfMonth */
    //Usage 01
    it('ax5.util.weeksOfMonth("2015-10-01")', function () {
        var obj = {
            year: 2015,
            month: 10,
            count: 1
        }
        should.deepEqual(ax5.util.weeksOfMonth("2015-10-01"), obj);
    });

    //Usage02
    it('ax5.util.weeksOfMonth("2015-09-19")', function () {
        var obj = {
            year: 2015,
            month: 9,
            count: 3
        }
        should.deepEqual(ax5.util.weeksOfMonth("2015-09-19"), obj);
    });

    //Usage03
    it('ax5.util.weeksOfMonth("2016-04-30")', function () {
        var obj = {
            year: 2016,
            month: 4,
            count: 5
        }
        should.deepEqual(ax5.util.weeksOfMonth("2016-04-30"), obj);
    });
    /* end ax5.util.weeksOfMonth */
});

describe('ax5.util.daysOfMonth TEST', function () {
    /* ax5.util.daysOfMonth*/
    //Usage 01
    it('ax5.util.daysOfMonth(2015,11)', function () {
        should.deepEqual(ax5.util.daysOfMonth(2015, 11), 31);
    });

    //Usage 02
    it('ax5.util.daysOfMonth(2015,1)', function () {
        should.deepEqual(ax5.util.daysOfMonth(2015, 1), 28);
    });

    //Usage 03
    it('ax5.util.daysOfMonth(2016,1)', function () {
        should.deepEqual(ax5.util.daysOfMonth(2016, 1), 29);
    });
    /* end ax5.util.daysOfMonth*/
});<commit_msg>update test code<commit_after>describe('ax5.util.date TEST', function () {
    /* ax5.util.date */
    //Usage 01
    it('ax5.util.date("2013-01-01")', function () {
        var date = new Date(2013, 0, 1);
        date.setHours(12);
        date.setMinutes(0);
        should.deepEqual(ax5.util.date('2013-01-01'), date);
    });

    //Usage 02
    it('ax5.util.date((new Date()) , {add:{d:10} , return:"yyyy/MM/dd"})', function () {
        var date = new Date();
        date.setDate(date.getDate() + 10);
        var str = date.getFullYear() + "/" + ax5.util.setDigit(date.getMonth() + 1, 2) + "/" + ax5.util.setDigit(date.getDate(), 2);

        should.deepEqual(ax5.util.date((new Date()), {add: {d: 10}, return: 'yyyy/MM/dd'}), str);
    });

    //Usage 03
    it('ax5.util.date("1919-03-01", {add:{d:10}, return:"yyyy/MM/dd hh:mm:ss"})', function () {
        should.deepEqual(ax5.util.date("1919-03-01", {add: {d: 10}, return: "yyyy/MM/dd hh:mm:ss"}), '1919/03/11 12:00:00');
    });

    //Usage 04
    it('ax5.util.date((new Date()) , {set:"firstDayOfMonth", return:"yyyy/MM/dd"})', function () {
        var date = new Date();
        var str = date.getFullYear() + "/" + ax5.util.setDigit(date.getMonth() + 1, 2) + "/01";
        should.deepEqual(ax5.util.date((new Date()), {set: "firstDayOfMonth", return: 'yyyy/MM/dd'}), str);
    });

    //Usage 05
    it('ax5.util.date((new Date()) , {set:"lastDayOfMonth", return:"yyyy/MM/dd"})', function () {
        var date = new Date();
        var str = date.getFullYear() + "/" + ax5.util.setDigit(date.getMonth() + 1, 2) + "/" + ax5.util.daysOfMonth(date.getFullYear(), date.getMonth());
        should.deepEqual(ax5.util.date((new Date()), {set: "lastDayOfMonth", return: 'yyyy/MM/dd'}), str);
    });

    //Usage 06
    it('ax5.util.date("20170411103317") [string.length == 14]', function () {
        var date = new Date(2017, 3, 11);
        date.setHours(10);
        date.setMinutes(33);
        date.setSeconds(17);
        should.deepEqual(ax5.util.date("20170411103317"), date);
    });

    //Usage 07
    it('ax5.util.date("201704") [string.length > 7]', function () {
        var date = new Date(2017, 3, 12);
        date.setHours(12);
        should.deepEqual(ax5.util.date("20170412"), date);
    });

    //Usage 08
    it('ax5.util.date("201704") [string.length > 4]', function () {
        var date = new Date(2017, 3);
        date.setHours(12);
        should.deepEqual(ax5.util.date("201704"), date);
    });

    //Usage 09
    it('ax5.util.date("2017") [string.length > 2]', function () {
        var date = new Date(2017, 0);
        date.setHours(12);
        should.deepEqual(ax5.util.date("2017"), date);
    });

    //Usage 10
    it('ax5.util.date("17") [string.length <= 2]', function () {
        var date = new Date();
        should.deepEqual(ax5.util.date("17"), date);
    });

    //Usage 11
    it('ax5.util.date(date, {return: "yyyy-MM-dd"})', function () {
        var date = new Date(2017, 3, 16);
        should.deepEqual(ax5.util.date(date, {return: "yyyy-MM-dd"}), "2017-04-16");
    });

    //Usage 12
    it('ax5.util.date(date, {return: "yyyy-MM-dd hh:mm:ss"})', function () {
        var date = new Date(2017, 3, 16, 12, 30, 15);
        should.deepEqual(ax5.util.date(date, {return: "yyyy-MM-dd hh:mm:ss"}), "2017-04-16 12:30:15");
    });

    //Usage 13
    it('ax5.util.date(date, {return: "dw"})', function () {
        var date = new Date(2017, 3, 16);
        should.deepEqual(ax5.util.date(date, {return: "dw"}), "SUN");
    });

    /* end ax5.util.date */
});

describe('ax5.util.dday TEST', function () {
    /* ax5.util.dday*/
    //Usage 01

    it('ax5.util.dday(new Date())', function () {
        should.deepEqual(ax5.util.dday(new Date()), 0);
    });

    //Usage 02
    it('ax5.util.dday("2016-01-29" , {today:"2016-01-28"})', function () {
        should.deepEqual(ax5.util.dday("2016-01-29", {today: "2016-01-28"}), 1);
    });

    //Usage 03
    it('ax5.util.dday("1977-03-29" , {today:"2016-01-28" , age:true})', function () {
        should.deepEqual(ax5.util.dday("1977-03-29", {today: "2016-01-28", age: true}), 39);
    });
    /* end ax5.util.dday*/
});

describe('ax5.util.weeksOfMonth TEST', function () {
    /* ax5.util.weeksOfMonth */
    //Usage 01
    it('ax5.util.weeksOfMonth("2015-10-01")', function () {
        var obj = {
            year: 2015,
            month: 10,
            count: 1
        }
        should.deepEqual(ax5.util.weeksOfMonth("2015-10-01"), obj);
    });

    //Usage02
    it('ax5.util.weeksOfMonth("2015-09-19")', function () {
        var obj = {
            year: 2015,
            month: 9,
            count: 3
        }
        should.deepEqual(ax5.util.weeksOfMonth("2015-09-19"), obj);
    });

    //Usage03
    it('ax5.util.weeksOfMonth("2016-04-30")', function () {
        var obj = {
            year: 2016,
            month: 4,
            count: 5
        }
        should.deepEqual(ax5.util.weeksOfMonth("2016-04-30"), obj);
    });
    /* end ax5.util.weeksOfMonth */
});

describe('ax5.util.daysOfMonth TEST', function () {
    /* ax5.util.daysOfMonth*/
    //Usage 01
    it('ax5.util.daysOfMonth(2015,11)', function () {
        should.deepEqual(ax5.util.daysOfMonth(2015, 11), 31);
    });

    //Usage 02
    it('ax5.util.daysOfMonth(2015,1)', function () {
        should.deepEqual(ax5.util.daysOfMonth(2015, 1), 28);
    });

    //Usage 03
    it('ax5.util.daysOfMonth(2016,1)', function () {
        should.deepEqual(ax5.util.daysOfMonth(2016, 1), 29);
    });
    /* end ax5.util.daysOfMonth*/
});<|endoftext|>


<commit_before>
seajs.config({
  base: './dependencies'
});

define(function(require, exports, mod) {

  var test = require('../../../test')
  require('./invalid')

  test.assert(('' in seajs.cache) === false, 'invalid dependencies should be removed')

  var a = "never-ending line\\";
  a ='\\';
  a = 1 / 2; //require("a2")

  a = 1 / 2
  require("./a")
  //require("b2")

  require('./a');
  require  ('b')
  require("b");
  var o = {
    require: function() {
    },
    f:require('./f')
  };
  o.require('d');
  o.require(require('e'   ));

  var $require = function() {};
  $require('$require');

  var xrequire = function() {};
  xrequire('xrequire');

  test.assert(require('./a').name === 'a', 'a');
  test.assert(require('b').name === 'b', 'b');
  test.assert(require('e').name === 'e', 'e');
  test.assert(mod.dependencies.length === 7, getFiles(mod.dependencies).join(' | '));

  test.next()

  function getFiles(uris) {
    var ret = []
    for (var i = 0; i < uris.length; i++) {
      ret[i] = uris[i].split('/').pop()
    }
    return ret
  }

  /**
   * @fileoverview Module authoring format.
   */

  var define = function() {
    // some comment
    var reg = /.*/g; // comment */
  }

  /* ok, I will disappear. */
  var s = '// i am string'; require('./x');
  var t = 'i am string too'; // require('z');

  /* will not // be removed */ var xx = 'a';

  //
  //     var Calendar = require('calendar');

  var str = " /* not a real comment */ ";
  var regex = /\/*.*/;
  var tt = '"\'';

  var xxxx = 'require("show_me_the_money")';

  var r = /\/*require('r')*/;
  var r2 = /require('r2')/;
  var weird = / \/\/ \/b\//g;

});

define('a', { name: 'a' });
define('b', { name: 'b' });
define('e', { name: 'e' });<commit_msg>Remove unique<commit_after>
seajs.config({
  base: './dependencies'
});

define(function(require, exports, mod) {

  var test = require('../../../test')
  require('./invalid')

  test.assert(('' in seajs.cache) === false, 'invalid dependencies should be removed')

  var a = "never-ending line\\";
  a ='\\';
  a = 1 / 2; //require("a2")

  a = 1 / 2
  require("./a")
  //require("b2")

  require('./a');
  require  ('b')
  require("b");
  var o = {
    require: function() {
    },
    f:require('./f')
  };
  o.require('d');
  o.require(require('e'   ));

  var $require = function() {};
  $require('$require');

  var xrequire = function() {};
  xrequire('xrequire');

  test.assert(require('./a').name === 'a', 'a');
  test.assert(require('b').name === 'b', 'b');
  test.assert(require('e').name === 'e', 'e');
  test.assert(mod.dependencies.length === 12, getFiles(mod.dependencies).join(' | '));

  test.next()

  function getFiles(uris) {
    var ret = []
    for (var i = 0; i < uris.length; i++) {
      ret[i] = uris[i].split('/').pop()
    }
    return ret
  }

  /**
   * @fileoverview Module authoring format.
   */

  var define = function() {
    // some comment
    var reg = /.*/g; // comment */
  }

  /* ok, I will disappear. */
  var s = '// i am string'; require('./x');
  var t = 'i am string too'; // require('z');

  /* will not // be removed */ var xx = 'a';

  //
  //     var Calendar = require('calendar');

  var str = " /* not a real comment */ ";
  var regex = /\/*.*/;
  var tt = '"\'';

  var xxxx = 'require("show_me_the_money")';

  var r = /\/*require('r')*/;
  var r2 = /require('r2')/;
  var weird = / \/\/ \/b\//g;

});

define('a', { name: 'a' });
define('b', { name: 'b' });
define('e', { name: 'e' });<|endoftext|>


<commit_before>/* eslint-disable */
/* bender-tags: editor,unit */
/* bender-ckeditor-plugins: wysiwygarea,structuredheadings,toolbar,basicstyles,dialog,richcombo,undo */
/* eslint-enable */

// Clean up all instances been created on the page.
(function () {

  var comboName = "NumFormats";

  bender.editor = {
    allowedForTests: "h1; h2; p"
  };

  bender.test({
    setUp: function () {
      //Anything to be run before each test if needed
    },

    "if no headings in document, the new heading is autonumbered": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new h2 has autonumbering set, since no prior heading exists
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied h2 block autonumberstyle"
        );
      });
    },

    "if previous heading is autonumber, the new heading is autonumbered": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
bar

^foo
");

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new h2 has autonumbering set, at the next level from h1
        assert.areSame(
            "
bar
" +
            "
^foo
",
            bot.htmlWithSelection(),
            "applied h2 block autonumber style"
        );
      });
    },

    "if previous heading is not autonumber, the new heading is not autonumbered": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
bar

^foo
");

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new heading doesn't have autonumbering, since the prior heading did not
        assert.areSame(
            "
bar

^foo
",
            bot.htmlWithSelection(),
            "applied h2 block non-autonumbered style"
        );
      });
    },

    "p option no-ops": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied p to p"
        );
      });
    },

    "p on autonumbered heading removes classes": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied p to h1"
        );
      });
    },

    "p on autonumbered heading in range removes classes": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection(
        "[
foo
" +
        "
bar
" +
        "
baz
]"
        );

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
foo

bar

baz
",
            bot.getData(),
            "applied p to h1 and it is classless"
        );
      });
    },

    "pre option on a p": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click pre
        combo.onClick("pre");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied pre to p"
        );
      });
    },

    "pre on autonumbered heading removes autonumbering classes": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click pre
        combo.onClick("pre");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied pre to h1"
        );
      });
    },

    "autonumbered heading is undoable": function () {
      var bot = this.editorBot;
      var initialHtmlWithSelection = "
^foo
";
      bot.setHtmlWithSelection(initialHtmlWithSelection);

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new h2 has autonumbering set, since no prior heading exists
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied h2 block autonumberstyle"
        );

        bot.execCommand("undo");
        assert.areSame(
            initialHtmlWithSelection,
            bot.htmlWithSelection(),
            "undid the heading"
        );
      });
    },

    "pre is undoable": function () {
      var bot = this.editorBot;
      var initialHtmlWithSelection = "
^foo
";
      bot.setHtmlWithSelection(initialHtmlWithSelection);

      bot.combo(comboName, function (combo) {
        // click pre
        combo.onClick("pre");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied pre to h1"
        );

        bot.execCommand("undo");
        assert.areSame(
          initialHtmlWithSelection,
          bot.htmlWithSelection(),
          "undid the pre"
        );
      });
    },

    "p on autonumbered heading is undoable": function () {
      var bot = this.editorBot;
      var initialHtmlWithSelection = "
^foo
";
      bot.setHtmlWithSelection(initialHtmlWithSelection);

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied p to h1"
        );

        bot.execCommand("undo");

        assert.areSame(
          initialHtmlWithSelection,
          bot.htmlWithSelection(),
          "undid the p"
        );
      });
    }

  });
})();
<commit_msg>teardown the preset in between tests<commit_after>/* eslint-disable */
/* bender-tags: editor,unit */
/* bender-ckeditor-plugins: wysiwygarea,structuredheadings,toolbar,basicstyles,dialog,richcombo,undo */
/* eslint-enable */

// Clean up all instances been created on the page.
(function () {

  var comboName = "NumFormats";

  bender.editor = {
    allowedForTests: "h1; h2; p"
  };

  bender.test({
    setUp: function () {
      //Anything to be run before each test if needed
    },

    tearDown: function () {
      var editor = this.editorBot.editor;
      editor.plugins.structuredheadings.currentPreset = null;
    },

    "if no headings in document, the new heading is autonumbered": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new h2 has autonumbering set, since no prior heading exists
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied h2 block autonumberstyle"
        );
      });
    },

    "if previous heading is autonumber, the new heading is autonumbered": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
bar

^foo
");

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new h2 has autonumbering set, at the next level from h1
        assert.areSame(
            "
bar
" +
            "
^foo
",
            bot.htmlWithSelection(),
            "applied h2 block autonumber style"
        );
      });
    },

    "if previous heading is not autonumber, the new heading is not autonumbered": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
bar

^foo
");

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new heading doesn't have autonumbering, since the prior heading did not
        assert.areSame(
            "
bar

^foo
",
            bot.htmlWithSelection(),
            "applied h2 block non-autonumbered style"
        );
      });
    },

    "p option no-ops": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied p to p"
        );
      });
    },

    "p on autonumbered heading removes classes": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied p to h1"
        );
      });
    },

    "p on autonumbered heading in range removes classes": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection(
        "[
foo
" +
        "
bar
" +
        "
baz
]"
        );

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
foo

bar

baz
",
            bot.getData(),
            "applied p to h1 and it is classless"
        );
      });
    },

    "pre option on a p": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click pre
        combo.onClick("pre");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied pre to p"
        );
      });
    },

    "pre on autonumbered heading removes autonumbering classes": function () {
      var bot = this.editorBot;
      bot.setHtmlWithSelection("
^foo
");

      bot.combo(comboName, function (combo) {
        // click pre
        combo.onClick("pre");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied pre to h1"
        );
      });
    },

    "autonumbered heading is undoable": function () {
      var bot = this.editorBot;
      var initialHtmlWithSelection = "
^foo
";
      bot.setHtmlWithSelection(initialHtmlWithSelection);

      bot.combo(comboName, function (combo) {
        // click h2
        combo.onClick("h2");
        // the new h2 has autonumbering set, since no prior heading exists
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied h2 block autonumberstyle"
        );

        bot.execCommand("undo");
        assert.areSame(
            initialHtmlWithSelection,
            bot.htmlWithSelection(),
            "undid the heading"
        );
      });
    },

    "pre is undoable": function () {
      var bot = this.editorBot;
      var initialHtmlWithSelection = "
^foo
";
      bot.setHtmlWithSelection(initialHtmlWithSelection);

      bot.combo(comboName, function (combo) {
        // click pre
        combo.onClick("pre");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied pre to h1"
        );

        bot.execCommand("undo");
        assert.areSame(
          initialHtmlWithSelection,
          bot.htmlWithSelection(),
          "undid the pre"
        );
      });
    },

    "p on autonumbered heading is undoable": function () {
      var bot = this.editorBot;
      var initialHtmlWithSelection = "
^foo
";
      bot.setHtmlWithSelection(initialHtmlWithSelection);

      bot.combo(comboName, function (combo) {
        // click p
        combo.onClick("p");
        assert.areSame(
            "
^foo
",
            bot.htmlWithSelection(),
            "applied p to h1"
        );

        bot.execCommand("undo");

        assert.areSame(
          initialHtmlWithSelection,
          bot.htmlWithSelection(),
          "undid the p"
        );
      });
    }

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


<commit_before>var fs = require('fs');
var assert = require('assert');
var config = require('./config.json');
var zmq = require('zmq');
var constants = require('bastly_constants');
var bunyan = require('bunyan');
var log = bunyan.createLogger({name: "tests"});

describe('Array', function() {
    describe('#indexOf()', function() {
        it('should return -1 when the value is not present', function() {
            assert.equal(-1, [1, 2, 3].indexOf(5));
            assert.equal(-1, [1, 2, 3].indexOf(0));
        });
    });
});

describe('Must receive pings', function() {
    it('It must receive zeromq pings', function (done) {

        var clientPings = require('../worker/clientPingsZeromq')();

        var pong = zmq.socket('sub');
        pong.connect('tcp://127.0.0.1:' + constants.PORT_PUB_SUB_CHASKI_CLIENT_PINGS);
        pong.subscribe('ping');
        pong.on('message', function(topic, data) {
            assert.equal(data, 'ping');
            clientPings.close();
            pong.close();
            done();
        });
    });
});

describe('Message Publisher', function() {
    it('It must publish zeromq messages', function (done) {

        var messagePublisher = require('../worker/messagePublisherZeromq')();

        var channel = 'fakeChannel';
        var reveiverUrl = 'tcp://127.0.0.1:' + constants.PORT_PUB_SUB_CHASKI_CLIENT_MESSAGES;
        log.info('connecting', reveiverUrl);
        var receiver = zmq.socket('sub');
        receiver.connect(reveiverUrl);
        receiver.subscribe(channel);
        var dataToPublish = 'fakeData';

        var sendFakeData = function (){
            messagePublisher.send(channel, dataToPublish);
        };
        setInterval(sendFakeData, 300);
        receiver.on('message', function(topic, data) {
            log.info('received');
            assert.equal(channel, topic);
            assert.equal(data, dataToPublish);
            messagePublisher.close();
            receiver.close();
            done();
        });
    });
});

describe('Data bus registers and listen to channel', function() {
    it('Receives messages', function (done) {
        var messagePublisher = {};
        messagePublisher.send = function(topic, data) {
            assert.equal(fakeChannel, topic.toString());
            assert.equal(dataToPublish, data.toString());
            busData.close();
            atahualpaMock.close();
            done();
        };
       var busData = require('../worker/busData')({log:log, messagePublisher:messagePublisher, "atahualpas": [{"ip": "127.0.0.1"}]});
        var fakeChannel = 'fake';
        var fakeApi = 'apkfake';
        var dataToPublish = 'holavato';
        var atahualpaMock = zmq.socket('pub');
        atahualpaMock.bind('tcp://*:' + constants.PORT_PUB_SUB_ATAHUALPA_CHASKI_MESSAGES);
        var sendFakeData = function (){
            atahualpaMock.send([fakeChannel, fakeChannel, fakeApi, dataToPublish]);
        };
        setInterval(sendFakeData, 10);
        busData.addChannel(fakeChannel);

    });
});

describe('BusOps ', function() {
    it('Registers new channel to listen and receives data in that channel', function (done) {
        var messagePublisher = {};
        messagePublisher.send = function(topic, data) {
            assert.equal(fakeChannel, topic.toString());
            assert.equal(dataToPublish, data.toString());
            busData.close();
            atahualpaMock.close();
            done();
        };
        var busData = require('../worker/busData')({log:log, messagePublisher:messagePublisher, "atahualpas": [{"ip": "127.0.0.1"}]});
        var atahualpaMockOps = zmq.socket('pub');
        var dataToPublish = 'holavato';
        atahualpaMockOps.bind('tcp://*:' + constants.PORT_PUB_SUB_ATAHUALPA_CHASKI_OPS);
        var fakeChannel = 'fakingit';
        var fakeApi = 'apkfake';
        var fakeChaskiID = 'AAA';
        var sendFakeOps = function (){
            atahualpaMockOps.send([fakeChaskiID, fakeChannel]);
        };
        var atahualpaMock = zmq.socket('pub');
        atahualpaMock.bind('tcp://*:' + constants.PORT_PUB_SUB_ATAHUALPA_CHASKI_MESSAGES);
        var sendFakeData = function (){
            atahualpaMock.send([fakeChannel, fakeChannel, fakeApi, dataToPublish]);
        };
        setInterval(sendFakeOps, 100);
        var busOps = require('../worker/busOps')({log:log, typeChaski:constants.CHASKI_TYPE_ZEROMQ, chaskiId:fakeChaskiID, busData:busData, "atahualpas": [{"ip": "127.0.0.1"}] });
        setInterval(sendFakeData, 100);

    });
});

//TODO missing tests for socketio
<commit_msg>added log to file for test to correctly report<commit_after>var fs = require('fs');
var assert = require('assert');
var config = require('./config.json');
var zmq = require('zmq');
var constants = require('bastly_constants');
var bunyan = require('bunyan');
var log = bunyan.createLogger
({
    name: "chaski-test",
    streams: [
        {
            path: '/var/log/chaski-test.log'
        }
    ]
});

describe('Array', function() {
    describe('#indexOf()', function() {
        it('should return -1 when the value is not present', function() {
            assert.equal(-1, [1, 2, 3].indexOf(5));
            assert.equal(-1, [1, 2, 3].indexOf(0));
        });
    });
});

describe('Must receive pings', function() {
    it('It must receive zeromq pings', function (done) {

        var clientPings = require('../worker/clientPingsZeromq')({log:log});

        var pong = zmq.socket('sub');
        pong.connect('tcp://127.0.0.1:' + constants.PORT_PUB_SUB_CHASKI_CLIENT_PINGS);
        pong.subscribe('ping');
        pong.on('message', function(topic, data) {
            assert.equal(data, 'ping');
            clientPings.close();
            pong.close();
            done();
        });
    });
});

describe('Message Publisher', function() {
    it('It must publish zeromq messages', function (done) {

        var messagePublisher = require('../worker/messagePublisherZeromq')({log:log});

        var channel = 'fakeChannel';
        var reveiverUrl = 'tcp://127.0.0.1:' + constants.PORT_PUB_SUB_CHASKI_CLIENT_MESSAGES;
        log.info('connecting', reveiverUrl);
        var receiver = zmq.socket('sub');
        receiver.connect(reveiverUrl);
        receiver.subscribe(channel);
        var dataToPublish = 'fakeData';

        var sendFakeData = function (){
            messagePublisher.send(channel, dataToPublish);
        };
        setInterval(sendFakeData, 300);
        receiver.on('message', function(topic, data) {
            log.info('received');
            assert.equal(channel, topic);
            assert.equal(data, dataToPublish);
            messagePublisher.close();
            receiver.close();
            done();
        });
    });
});

describe('Data bus registers and listen to channel', function() {
    it('Receives messages', function (done) {
        var messagePublisher = {};
        messagePublisher.send = function(topic, data) {
            assert.equal(fakeChannel, topic.toString());
            assert.equal(dataToPublish, data.toString());
            busData.close();
            atahualpaMock.close();
            done();
        };
       var busData = require('../worker/busData')({log:log, messagePublisher:messagePublisher, "atahualpas": [{"ip": "127.0.0.1"}]});
        var fakeChannel = 'fake';
        var fakeApi = 'apkfake';
        var dataToPublish = 'holavato';
        var atahualpaMock = zmq.socket('pub');
        atahualpaMock.bind('tcp://*:' + constants.PORT_PUB_SUB_ATAHUALPA_CHASKI_MESSAGES);
        var sendFakeData = function (){
            atahualpaMock.send([fakeChannel, fakeChannel, fakeApi, dataToPublish]);
        };
        setInterval(sendFakeData, 10);
        busData.addChannel(fakeChannel);

    });
});

describe('BusOps ', function() {
    it('Registers new channel to listen and receives data in that channel', function (done) {
        var messagePublisher = {};
        messagePublisher.send = function(topic, data) {
            assert.equal(fakeChannel, topic.toString());
            assert.equal(dataToPublish, data.toString());
            busData.close();
            atahualpaMock.close();
            done();
        };
        var busData = require('../worker/busData')({log:log, messagePublisher:messagePublisher, "atahualpas": [{"ip": "127.0.0.1"}]});
        var atahualpaMockOps = zmq.socket('pub');
        var dataToPublish = 'holavato';
        atahualpaMockOps.bind('tcp://*:' + constants.PORT_PUB_SUB_ATAHUALPA_CHASKI_OPS);
        var fakeChannel = 'fakingit';
        var fakeApi = 'apkfake';
        var fakeChaskiID = 'AAA';
        var sendFakeOps = function (){
            atahualpaMockOps.send([fakeChaskiID, fakeChannel]);
        };
        var atahualpaMock = zmq.socket('pub');
        atahualpaMock.bind('tcp://*:' + constants.PORT_PUB_SUB_ATAHUALPA_CHASKI_MESSAGES);
        var sendFakeData = function (){
            atahualpaMock.send([fakeChannel, fakeChannel, fakeApi, dataToPublish]);
        };
        setInterval(sendFakeOps, 100);
        var busOps = require('../worker/busOps')({log:log, typeChaski:constants.CHASKI_TYPE_ZEROMQ, chaskiId:fakeChaskiID, busData:busData, "atahualpas": [{"ip": "127.0.0.1"}] });
        setInterval(sendFakeData, 100);

    });
});

//TODO missing tests for socketio
<|endoftext|>


<commit_before>import Ember from 'ember';
import { TestModuleForComponent } from 'ember-test-helpers';
import test from 'tests/test-support/qunit-test';
import qunitModuleFor from 'tests/test-support/qunit-module-for';
import { setResolverRegistry } from 'tests/test-support/resolver';

function moduleForComponent(name, description, callbacks) {
  var module = new TestModuleForComponent(name, description, callbacks);
  qunitModuleFor(module);
}

var PrettyColor = Ember.Component.extend({
  classNames: ['pretty-color'],
  attributeBindings: ['style'],
  style: function(){
    return new Ember.Handlebars.SafeString('color: ' + this.get('name') + ';');
  }.property('name')
});

var ColorController = Ember.ObjectController.extend({
  hexa: function() {
    switch( this.get('model') ) {
      case 'red':
        return '0xFF0000';
      case 'green':
        return '0x00FF00';
      case 'blue':
        return '0x0000FF';
    }
  }.property('model')
});

var BoringColor = Ember.Component.extend({
  willDestroyElement: function(){
    var stateIndicatesInDOM = (this._state === 'inDOM');
    var actuallyInDOM = Ember.$.contains(document, this.$()[0]);

    ok((actuallyInDOM === true) && (actuallyInDOM === stateIndicatesInDOM), 'component should still be in the DOM');
  }
});

function setupRegistry() {
  setResolverRegistry({
    'component:x-foo': Ember.Component.extend(),
    'component:pretty-color': PrettyColor,
    'component:boring-color': BoringColor,
    'template:components/pretty-color': Ember.Handlebars.compile('Pretty Color: {{name}}'),
    'controller:color': ColorController
  });
}

///////////////////////////////////////////////////////////////////////////////

var originalDeprecate;
moduleForComponent('x-foo', {
  needs: ['controller:color'],

  setup: function() {
    originalDeprecate = Ember.deprecate;
  },

  teardown: function() {
    Ember.deprecate = originalDeprecate;
  },

  beforeSetup: function() {
    setupRegistry();
  }
});

test('renders', function() {
  expect(2);
  var component = this.subject();
  equal(component._state, 'preRender');
  this.render();
  equal(component._state, 'inDOM');
});

test('append', function() {
  expect(4);

  var deprecations = [];
  var $el;
  var component;

  // capture all deprecations so they can be checked later
  Ember.deprecate = function(message) {
    deprecations.push(message);
  };
  component = this.subject();
  equal(component._state, 'preRender');
  $el = this.append();
  equal(component._state, 'inDOM');
  ok($el && $el.length, 'append returns $el');
  ok(Ember.A(deprecations).contains('this.append() is deprecated. Please use this.render() or this.$() instead.'));
});

test('yields', function() {
  expect(2);
  var component = this.subject({
    layout: Ember.Handlebars.compile("yield me")
  });
  equal(component._state, 'preRender');
  this.render();
  equal(component._state, 'inDOM');
});

test('can lookup components in its layout', function() {
  expect(1);
  var component = this.subject({
    layout: Ember.Handlebars.compile("{{x-foo id='yodawg-i-heard-you-liked-x-foo-in-ur-x-foo'}}")
  });
  this.render();
  equal(component._state, 'inDOM');
});

test('can use the component keyword in its layout', function() {
  expect(1);
  var component = this.subject({
    colors: ['red', 'green', 'blue'],
    layout: Ember.Handlebars.compile("{{component 'x-foo'}}")
  });
  this.render();
  equal(component._state, 'inDOM');
});

test('clears out views from test to test', function() {
  expect(1);
  this.subject({
    layout: Ember.Handlebars.compile("{{x-foo id='yodawg-i-heard-you-liked-x-foo-in-ur-x-foo'}}")
  });
  this.render();
  ok(true, 'rendered without id already being used from another test');
});

///////////////////////////////////////////////////////////////////////////////

moduleForComponent('pretty-color', {
  unit: true,
  beforeSetup: function() {
    setupRegistry();
  }
});

test("className", function(){
  // first call to this.$() renders the component.
  ok(this.$().is('.pretty-color'));
});

test("template", function(){
  var component = this.subject();

  equal($.trim(this.$().text()), 'Pretty Color:');

  Ember.run(function(){
    component.set('name', 'green');
  });

  equal($.trim(this.$().text()), 'Pretty Color: green');
});

test("$", function(){
  var component = this.subject({name: 'green'});
  equal($.trim(this.$('.color-name').text()), 'green');
  equal($.trim(this.$().text()), 'Pretty Color: green');
});

moduleForComponent('pretty-color', 'component:pretty-color -- this.render in setup', {
  unit: true,
  beforeSetup: function() {
    setupRegistry();
  },

  setup: function() {
    this.subject({
      name: 'red'
    });

    this.render();
  }
});

test("className", function(){
  // calling `this.$` or `this.subject.$` would
  // force it to `render` initially, so we access the `ember-testing`
  // div contents directly
  equal($.trim($('#ember-testing').text()), 'Pretty Color: red');
});

moduleForComponent('boring-color', 'component:boring-color -- still in DOM in willDestroyElement', {
  unit: true,
  beforeSetup: function() {
    setupRegistry();
  },

  setup: function() {
    this.render();
  }
});

test("className", function(){
  expect(1);
  // the assertion is in the willDestroyElement() hook of the component
});

var testModule;
module('moduleForComponent: can be invoked with only the component name', {
  beforeEach: function(assert) {
    var done = assert.async();
    testModule = new TestModuleForComponent('pretty-color', { unit: true });
    testModule.setup()['finally'](done);
  },

  afterEach: function(assert) {
    var done = assert.async();
    testModule.teardown()['finally'](done);
  }
});

test('it allows missing callbacks', function() {
  ok(true, 'no errors are thrown');
});

var testModule;
module('moduleForComponent: can be invoked with the component name and description', {
  beforeEach: function(assert) {
    var done = assert.async();
    testModule = new TestModuleForComponent('pretty-color', 'PrettyColor', { unit: true });
    testModule.setup()['finally'](done);
  },

  afterEach: function(assert) {
    var done = assert.async();
    testModule.teardown()['finally'](done);
  }
});

test('it allows missing callbacks', function() {
  ok(true, 'no errors are thrown');
});
<commit_msg>Added test<commit_after>import Ember from 'ember';
import { TestModuleForComponent } from 'ember-test-helpers';
import test from 'tests/test-support/qunit-test';
import qunitModuleFor from 'tests/test-support/qunit-module-for';
import { setResolverRegistry } from 'tests/test-support/resolver';

function moduleForComponent(name, description, callbacks) {
  var module = new TestModuleForComponent(name, description, callbacks);
  qunitModuleFor(module);
}

var PrettyColor = Ember.Component.extend({
  classNames: ['pretty-color'],
  attributeBindings: ['style'],
  style: function(){
    return new Ember.Handlebars.SafeString('color: ' + this.get('name') + ';');
  }.property('name')
});

var ColorController = Ember.ObjectController.extend({
  hexa: function() {
    switch( this.get('model') ) {
      case 'red':
        return '0xFF0000';
      case 'green':
        return '0x00FF00';
      case 'blue':
        return '0x0000FF';
    }
  }.property('model')
});

var BoringColor = Ember.Component.extend({
  willDestroyElement: function(){
    var stateIndicatesInDOM = (this._state === 'inDOM');
    var actuallyInDOM = Ember.$.contains(document, this.$()[0]);

    ok((actuallyInDOM === true) && (actuallyInDOM === stateIndicatesInDOM), 'component should still be in the DOM');
  }
});

function setupRegistry() {
  setResolverRegistry({
    'component:x-foo': Ember.Component.extend(),
    'component:pretty-color': PrettyColor,
    'component:boring-color': BoringColor,
    'template:components/pretty-color': Ember.Handlebars.compile('Pretty Color: {{name}}'),
    'controller:color': ColorController
  });
}

///////////////////////////////////////////////////////////////////////////////

var originalDeprecate;
moduleForComponent('x-foo', {
  needs: ['controller:color'],

  setup: function() {
    originalDeprecate = Ember.deprecate;
  },

  teardown: function() {
    Ember.deprecate = originalDeprecate;
  },

  beforeSetup: function() {
    setupRegistry();
  }
});

test('renders', function() {
  expect(2);
  var component = this.subject();
  equal(component._state, 'preRender');
  this.render();
  equal(component._state, 'inDOM');
});

test('append', function() {
  expect(4);

  var deprecations = [];
  var $el;
  var component;

  // capture all deprecations so they can be checked later
  Ember.deprecate = function(message) {
    deprecations.push(message);
  };
  component = this.subject();
  equal(component._state, 'preRender');
  $el = this.append();
  equal(component._state, 'inDOM');
  ok($el && $el.length, 'append returns $el');
  ok(Ember.A(deprecations).contains('this.append() is deprecated. Please use this.render() or this.$() instead.'));
});

test('yields', function() {
  expect(2);
  var component = this.subject({
    layout: Ember.Handlebars.compile("yield me")
  });
  equal(component._state, 'preRender');
  this.render();
  equal(component._state, 'inDOM');
});

test('can lookup components in its layout', function() {
  expect(1);
  var component = this.subject({
    layout: Ember.Handlebars.compile("{{x-foo id='yodawg-i-heard-you-liked-x-foo-in-ur-x-foo'}}")
  });
  this.render();
  equal(component._state, 'inDOM');
});

test('can use the component keyword in its layout', function() {
  expect(1);
  var component = this.subject({
    colors: ['red', 'green', 'blue'],
    layout: Ember.Handlebars.compile("{{component 'x-foo'}}")
  });
  this.render();
  equal(component._state, 'inDOM');
});

test('clears out views from test to test', function() {
  expect(1);
  this.subject({
    layout: Ember.Handlebars.compile("{{x-foo id='yodawg-i-heard-you-liked-x-foo-in-ur-x-foo'}}")
  });
  this.render();
  ok(true, 'rendered without id already being used from another test');
});

///////////////////////////////////////////////////////////////////////////////

moduleForComponent('pretty-color', {
  unit: true,
  beforeSetup: function() {
    setupRegistry();
  }
});

test("className", function(){
  // first call to this.$() renders the component.
  ok(this.$().is('.pretty-color'));
});

test("template", function(){
  var component = this.subject();

  equal($.trim(this.$().text()), 'Pretty Color:');

  Ember.run(function(){
    component.set('name', 'green');
  });

  equal($.trim(this.$().text()), 'Pretty Color: green');
});

test("$", function(){
  var component = this.subject({name: 'green'});
  equal($.trim(this.$('.color-name').text()), 'green');
  equal($.trim(this.$().text()), 'Pretty Color: green');
});

moduleForComponent('pretty-color', 'component:pretty-color -- this.render in setup', {
  unit: true,
  beforeSetup: function() {
    setupRegistry();
  },

  setup: function() {
    this.subject({
      name: 'red'
    });

    this.render();
  }
});

test("className", function(){
  // calling `this.$` or `this.subject.$` would
  // force it to `render` initially, so we access the `ember-testing`
  // div contents directly
  equal($.trim($('#ember-testing').text()), 'Pretty Color: red');
});

moduleForComponent('boring-color', 'component:boring-color -- still in DOM in willDestroyElement', {
  unit: true,
  beforeSetup: function() {
    setupRegistry();
  },

  setup: function() {
    this.render();
  }
});

test("className", function(){
  expect(1);
  // the assertion is in the willDestroyElement() hook of the component
});

var testModule;
module('moduleForComponent: can be invoked with only the component name', {
  beforeEach: function(assert) {
    var done = assert.async();
    testModule = new TestModuleForComponent('pretty-color', { unit: true });
    testModule.setup()['finally'](done);
  },

  afterEach: function(assert) {
    var done = assert.async();
    testModule.teardown()['finally'](done);
  }
});

test('it allows missing callbacks', function() {
  ok(true, 'no errors are thrown');
});

var testModule;
module('moduleForComponent: can be invoked with the component name and description', {
  beforeEach: function(assert) {
    var done = assert.async();
    testModule = new TestModuleForComponent('pretty-color', 'PrettyColor', { unit: true });
    testModule.setup()['finally'](done);
  },

  afterEach: function(assert) {
    var done = assert.async();
    testModule.teardown()['finally'](done);
  }
});

test('it allows missing callbacks', function() {
  ok(true, 'no errors are thrown');
});

moduleForComponent('x-bad', {
    needs: ['mis:sing'],
    beforeEach: function(assert) {
      // won't be called because of setup error
      var done = assert.async();
      assert.ok(true);
      done();
    }
});

test('it happens', function() {
  expect(0);
});
<|endoftext|>


<commit_before>import expect from 'expect';

import findRouteByComponent from '../../src/util/findRouteByComponent';

describe('findRouteByComponent', () => {
  const component = () => {};
  it('Returns undefined for empty routes', () => {
    expect(findRouteByComponent(component, [])).toMatch({});
  });
  it('Returns the first matched route', () => {
    const routes = [
      {
        component: function notThisOne() {},
      },
      {
        component,
      },
    ];
    expect(findRouteByComponent(component, routes)).toMatch({ route: routes[1] });
  });
});
<commit_msg>Adds more tests and better test labels<commit_after>import expect from 'expect';

import findRouteByComponent from '../../src/util/findRouteByComponent';

describe('findRouteByComponent', () => {
  const component = () => {};
  it('Returns an empty object for empty routes', () => {
    expect(findRouteByComponent(component, [])).toEqual({});
  });
  it('Returns an empty object when the component cannot be found among the routes', () => {
    const routes = [
      {
        component: function notThisOne() {},
      },
      {
        component: function andNotThisOnceEither() {},
      },
    ];
    expect(findRouteByComponent(component, routes)).toEqual({});
  });
  it('Returns the first matched route', () => {
    const routes = [
      {
        component: function notThisOne() {},
      },
      {
        component,
      },
    ];
    expect(findRouteByComponent(component, routes)).toEqual({ route: routes[1] });
  });
  it('Handles `components` for named routes', () => {
    const routes = [
      {
        component: function ARouteHandler() {},
      },
      {
        components: {
          a: function AScreen() {},
          b: function BScreen() {},
          c: component,
          d: function DScreen() {},
        },
      },
    ];
    expect(findRouteByComponent(component, routes)).toEqual({ route: routes[1], name: 'c' });
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
import Button from './../app/components/Button';
import Heading from './../app/components/Heading';

storiesOf('Button', module)
  .addWithInfo(
    'with label',
    `Basic Usage of Button`,
    () => (
    <Button onClick={action('clicked')} label="Hello Button">
      Child Element
    </Button>
  ))
  .add('with href', () => (
    <Button href="http://google.com" onClick={action('clicked')} label="Hello Button">
      Child Element
    </Button>
  ))
  .add('with children', () => (
    <Button onClick={action('clicked')}>
      Child Element
    </Button>
  ))
  .add('with some emoji', () => (
    <Button onClick={action('clicked')} label="">
      😀 😎 👍 💯
    </Button>
  ));

storiesOf('Heading', module)
  .add('1', () => (
    <Heading order={1}>
      Child Element
    </Heading>
  ))
  .add('2', () => (
    <Heading order={2}>
      Child Element
    </Heading>
  ))
  .add('3', () => (
    <Heading order={3}>
      Child Element
    </Heading>
  ))
  .add('4', () => (
    <Heading order={4}>
      Child Element
    </Heading>
  ));
<commit_msg>enabled editable props<commit_after>import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
import { withKnobs, text, boolean, number } from '@kadira/storybook-addon-knobs';
import Button from './../app/components/Button';
import Heading from './../app/components/Heading';

storiesOf('Button', module)
  .addDecorator(withKnobs)
  .addWithInfo(
    'Basic',
    `Basic Usage of a Link Element.`,
    () => (
    <Button href={text("href", "http://google.com")}>
      {text("Label", "Basic Usage")}
    </Button>
  ))
  .addWithInfo(
    'with Icon',
    `Link Element with Icon. By default, icons will be positioned before element children`,
    () => (
    <Button href={text("href", "http://google.com")} icon={text("icon", "overview")}>
      {text("Label", "Link with Icon")}
    </Button>
  ))
  .addWithInfo(
    'with trailing icon',
    `Link Element with Icon. To override default positioning, icon-position parameter can be specified`,
    () => (
    <Button href={text("href", "http://google.com")} icon={text("icon", "external")} icon-trailing={boolean("Trailing Icon", true)}>
      {text("Label", "Link with trailing Icon")}
    </Button>
  ))
  .addWithInfo(
    'with onClick listener',
    `Instead of an href, an onClick listener can be specified. In this case, a button will be rendered out instead of an a.`,
    () => (
    <Button onClick={action('clicked')}>
      {text("Label", "Link with onClick listener")}
    </Button>
  ));

storiesOf('Heading', module)
  .add('1', () => (
    <Heading order={1}>
      Child Element
    </Heading>
  ))
  .add('2', () => (
    <Heading order={2}>
      Child Element
    </Heading>
  ))
  .add('3', () => (
    <Heading order={3}>
      Child Element
    </Heading>
  ))
  .add('4', () => (
    <Heading order={4}>
      Child Element
    </Heading>
  ));
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import { checkA11y } from 'storybook-addon-a11y';
import { withInfo } from '@storybook/addon-info';
import { withKnobs, boolean } from '@storybook/addon-knobs/react';
import { Store, State } from '@sambego/storybook-state';
import { RadioGroup, RadioButton } from '../components';

const sizes = ['small', 'medium', 'large'];

const store = new Store({
  value: 'small',
});
const updateState = value => {
  store.set({ value });
};

storiesOf('Radio', module)
  .addDecorator((story, context) => withInfo('common info')(story)(context))
  .addDecorator(checkA11y)
  .addDecorator(withKnobs)
  .add('Sizes', () => (
    <State store={store}>
      <RadioGroup name="stringValue" onChange={updateState}>
        {sizes.map((size, key) => (
          <RadioButton
            key={key}
            size={size}
            marginVertical={3}
            label={`I'm a ${size} radio`}
            value={size}
            disabled={boolean('Disabled', false)}
          />
        ))}
      </RadioGroup>
    </State>
  ));
<commit_msg>Pagination: implement Knobs<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import { checkA11y } from 'storybook-addon-a11y';
import { withInfo } from '@storybook/addon-info';
import { withKnobs, boolean, select } from '@storybook/addon-knobs/react';
import { Store, State } from '@sambego/storybook-state';
import { RadioGroup, RadioButton } from '../components';

const sizes = ['small', 'medium', 'large'];
const values = ['Option one', 'Option two', 'Option three'];

const store = new Store({
  value: 'Option one',
});
const updateState = value => {
  store.set({ value });
};

storiesOf('Radio', module)
  .addDecorator((story, context) => withInfo('common info')(story)(context))
  .addDecorator(checkA11y)
  .addDecorator(withKnobs)
  .add('Basic', () => (
    <State store={store}>
      <RadioGroup name="stringValue" onChange={updateState}>
        {values.map((value, key) => (
          <RadioButton
            key={key}
            size={select('Size', sizes, 'medium')}
            marginVertical={3}
            label={value}
            value={value}
            disabled={boolean('Disabled', false)}
          />
        ))}
      </RadioGroup>
    </State>
  ));
<|endoftext|>


<commit_before>// A test script to assist in figuring out why express-couchuser doesn't work with pouch
// TODO:  Figure out how to debug this properly from within WebStorm

// Configure a testEnvironment with an express server, pouch instance, and outgoing mail server.
"use strict";
var fluid      = fluid || require("infusion");
var path       = require("path");

require("gpii-express");
require("gpii-handlebars");

require("gpii-pouch");
require("gpii-mail-test");

require("../../src/js/server");

// We use just the request-handling bits of the kettle stack in our tests, but we include the whole thing to pick up the base grades
//require("../../node_modules/kettle");
//require("../../node_modules/kettle/lib/test/KettleTestUtils");

var gpii = fluid.registerNamespace("gpii");
fluid.registerNamespace("gpii.express.couchuser.tests.pouch.testEnvironment");

var bowerDir        = path.resolve(__dirname, "../../bower_components");
var jsDir           = path.resolve(__dirname, "../../src/js");
var mailTemplateDir = path.resolve(__dirname, "../templates");
var modulesDir      = path.resolve(__dirname, "../../node_modules");

var userDataFile    = path.resolve(__dirname, "../data/users/users.json");
var viewDir         = path.resolve(__dirname, "../views");

fluid.defaults("gpii.express.couchuser.tests.pouch.testEnvironment", {
    //gradeNames: ["fluid.test.testEnvironment", "autoInit"],
    gradeNames: ["fluid.standardRelayComponent", "autoInit"],
    port:   7532,
    baseUrl: "http://localhost/",
    components: {
        express: {
            type: "gpii.express",
            //createOnEvent: "constructServer",
            options: {
                listeners: {
                    "started": "{testEnvironment}.events.expressStarted.fire"
                },
                config: {
                    express: {
                        "port" :   "{testEnvironment}.options.port",
                        baseUrl: "{testEnvironment}.options.baseUrl",
                        views:   viewDir,
                        session: {
                            secret: "Printer, printer take a hint-ter."
                        }
                    },
                    app: {
                        name: "GPII Express Couchuser Test Server",
                        url:  "{testEnvironment}.options.baseUrl"
                    },
                    users: "http://localhost:7534/_users",
                    request_defaults: {
                        auth: {
                            user: "admin",
                            pass: "admin"
                        }
                    },
                    email:  {
                        from: "no-reply@ul.gpii.net",
                        service: "SMTP",
                        SMTP: {
                            host: "localhost",
                            port: 4029
                        },
                        templateDir: mailTemplateDir
                    },
                    verify: true,
                    safeUserFields: "name email displayName",
                    adminRoles: [ "admin"]
                },
                components: {
                    json: {
                        type: "gpii.express.middleware.bodyparser.json"
                    },
                    urlencoded: {
                        type: "gpii.express.middleware.bodyparser.urlencoded"
                    },
                    cookieparser: {
                        type: "gpii.express.middleware.cookieparser"
                    },
                    session: {
                        type: "gpii.express.middleware.session"
                    },
                    user: {
                        type: "gpii.express.couchuser.server"
                    },
                    modules: {
                        type:  "gpii.express.router.static",
                        options: {
                            path:    "/modules",
                            content: modulesDir
                        }
                    },
                    js: {
                        type:  "gpii.express.router.static",
                        options: {
                            path:    "/js",
                            content: jsDir
                        }
                    },
                    bc: {
                        type:  "gpii.express.router.static",
                        options: {
                            path:    "/bc",
                            content: bowerDir
                        }
                    },
                    handlebars: {
                        type: "gpii.express.hb"
                    },
                    content: {
                        type: "gpii.express.hb.dispatcher",
                        options: {
                            path:    "/content/:template"
                        }
                    },
                    inline: {
                        type: "gpii.express.hb.inline",
                        options: {
                            path: "/hbs"
                        }
                    }
                }
            }
        },
        pouch: {
            type: "gpii.express",
            options: {
                listeners: {
                    "started": "{testEnvironment}.events.pouchStarted.fire"
                },
                config: {
                    express: {
                        "port" :   7534,
                        baseUrl: "http://localhost:7534/"
                    },
                    app: {
                        name: "Pouch Test Server",
                        url: "http://localhost:7534/"
                    }
                },
                components: {
                    pouch: {
                        type: "gpii.pouch",
                        options: {
                            path: "/",
                            model: {
                                databases: {
                                    _users: {
                                        data: userDataFile
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        smtp: {
            type: "gpii.test.mail.smtp",
            //createOnEvent: "constructServer",
            options: {
                listeners: {
                    "ready": "{testEnvironment}.events.smtpStarted.fire"
                },
                config: {
                    port: 4029
                }
            }
        }
        //,
        //testCaseHolder: {
        //    type: "gpii.express.couchuser.test.server.caseHolder"
        //}
    },
    events: {
        constructServer: null,
        messageReceived: null,
        expressStarted:  null,
        pouchStarted:    null,
        smtpStarted:     null,
        started: {
            events: {
                expressStarted: "expressStarted",
                pouchStarted:   "{pouch}.events.started",
                smtpStarted:    "smtpStarted"
            }
        }
    }
});

gpii.express.couchuser.tests.pouch.testEnvironment({});
<commit_msg>Updated to use newer event names.<commit_after>// A test script to assist in figuring out why express-couchuser doesn't work with pouch
// TODO:  Figure out how to debug this properly from within WebStorm

// Configure a testEnvironment with an express server, pouch instance, and outgoing mail server.
"use strict";
var fluid      = fluid || require("infusion");
var path       = require("path");

require("gpii-express");
require("gpii-handlebars");

require("gpii-pouch");
require("gpii-mail-test");

require("../../src/js/server");

// We use just the request-handling bits of the kettle stack in our tests, but we include the whole thing to pick up the base grades
//require("../../node_modules/kettle");
//require("../../node_modules/kettle/lib/test/KettleTestUtils");

var gpii = fluid.registerNamespace("gpii");
fluid.registerNamespace("gpii.express.couchuser.tests.pouch.testEnvironment");

var bowerDir        = path.resolve(__dirname, "../../bower_components");
var jsDir           = path.resolve(__dirname, "../../src/js");
var mailTemplateDir = path.resolve(__dirname, "../templates");
var modulesDir      = path.resolve(__dirname, "../../node_modules");

var userDataFile    = path.resolve(__dirname, "../data/users/users.json");
var viewDir         = path.resolve(__dirname, "../views");

fluid.defaults("gpii.express.couchuser.tests.pouch.testEnvironment", {
    //gradeNames: ["fluid.test.testEnvironment", "autoInit"],
    gradeNames: ["fluid.standardRelayComponent", "autoInit"],
    port:   7532,
    baseUrl: "http://localhost/",
    components: {
        express: {
            type: "gpii.express",
            //createOnEvent: "constructServer",
            options: {
                listeners: {
                    "onReady": "{testEnvironment}.events.expressStarted.fire"
                },
                config: {
                    express: {
                        "port" :   "{testEnvironment}.options.port",
                        baseUrl: "{testEnvironment}.options.baseUrl",
                        views:   viewDir,
                        session: {
                            secret: "Printer, printer take a hint-ter."
                        }
                    },
                    app: {
                        name: "GPII Express Couchuser Test Server",
                        url:  "{testEnvironment}.options.baseUrl"
                    },
                    users: "http://localhost:7534/_users",
                    request_defaults: {
                        auth: {
                            user: "admin",
                            pass: "admin"
                        }
                    },
                    email:  {
                        from: "no-reply@ul.gpii.net",
                        service: "SMTP",
                        SMTP: {
                            host: "localhost",
                            port: 4029
                        },
                        templateDir: mailTemplateDir
                    },
                    verify: true,
                    safeUserFields: "name email displayName",
                    adminRoles: [ "admin"]
                },
                components: {
                    json: {
                        type: "gpii.express.middleware.bodyparser.json"
                    },
                    urlencoded: {
                        type: "gpii.express.middleware.bodyparser.urlencoded"
                    },
                    cookieparser: {
                        type: "gpii.express.middleware.cookieparser"
                    },
                    session: {
                        type: "gpii.express.middleware.session"
                    },
                    user: {
                        type: "gpii.express.couchuser.server"
                    },
                    modules: {
                        type:  "gpii.express.router.static",
                        options: {
                            path:    "/modules",
                            content: modulesDir
                        }
                    },
                    js: {
                        type:  "gpii.express.router.static",
                        options: {
                            path:    "/js",
                            content: jsDir
                        }
                    },
                    bc: {
                        type:  "gpii.express.router.static",
                        options: {
                            path:    "/bc",
                            content: bowerDir
                        }
                    },
                    handlebars: {
                        type: "gpii.express.hb"
                    },
                    content: {
                        type: "gpii.express.hb.dispatcher",
                        options: {
                            path:    "/content/:template"
                        }
                    },
                    inline: {
                        type: "gpii.express.hb.inline",
                        options: {
                            path: "/hbs"
                        }
                    }
                }
            }
        },
        pouch: {
            type: "gpii.express",
            options: {
                listeners: {
                    "onReady": "{testEnvironment}.events.pouchStarted.fire"
                },
                config: {
                    express: {
                        "port" :   7534,
                        baseUrl: "http://localhost:7534/"
                    },
                    app: {
                        name: "Pouch Test Server",
                        url: "http://localhost:7534/"
                    }
                },
                components: {
                    pouch: {
                        type: "gpii.pouch",
                        options: {
                            path: "/",
                            model: {
                                databases: {
                                    _users: {
                                        data: userDataFile
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        smtp: {
            type: "gpii.test.mail.smtp",
            //createOnEvent: "constructServer",
            options: {
                listeners: {
                    "ready": "{testEnvironment}.events.smtpStarted.fire"
                },
                config: {
                    port: 4029
                }
            }
        }
        //,
        //testCaseHolder: {
        //    type: "gpii.express.couchuser.test.server.caseHolder"
        //}
    },
    events: {
        constructServer: null,
        messageReceived: null,
        expressStarted:  null,
        pouchStarted:    null,
        smtpStarted:     null,
        onReady: {
            events: {
                expressStarted: "expressStarted",
                pouchStarted:   "{pouch}.events.onStarted",
                smtpStarted:    "smtpStarted"
            }
        }
    }
});

gpii.express.couchuser.tests.pouch.testEnvironment({});
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var Promise = require("bluebird");
var request = require("request");
var stream = require('stream');
var https = require('https');
var http = require('http');
var util = require('util');
var mime = require('mime');
var path = require('path');
var URL = require('url');
var fs = require('fs');

var requestPromise = Promise.promisify(request);

/**
 * Both request method to obtain messages are implemented. To use standard polling, set `polling: true`
 * on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a valid (not self signed) SSL certificate.
 * Emmits `message` when a message arrives.
 *
 * @class TelegramBot
 * @constructor
 * @param {String} token Bot Token
 * @param {Object} [options]
 * @param {Boolean|Object} [options.polling=false] Set true to enable polling
 * @param {String|Number} [options.polling.timeout=4] Polling time
 * @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook
 * @param {String} [options.webHook.key] PEM private key to webHook server
 * @param {String} [options.webHook.cert] PEM certificate key to webHook server
 * @see https://core.telegram.org/bots/api
 */
var TelegramBot = function (token, options) {
  options = options || {};
  this.token = token;
  this.offset = 0;
  this._webServer = null;

  if (options.polling) {
    // By default polling for 4 seconds
    var timeout = options.polling.timeout || 4;
    this._polling(timeout);
  }

  if (options.webHook) {
    var port = options.webHook.port || 8443;
    var key = options.webHook.key;
    var cert = options.webHook.cert;
    var host = options.webHook.host;
    this._configureWebHook(port, host, key, cert);
  }
};

util.inherits(TelegramBot, EventEmitter);

TelegramBot.prototype._configureWebHook = function (port, host, key, cert) {
  var protocol = 'HTTP';
  var self = this;

  if (key && cert) { // HTTPS Server
    protocol = 'HTTPS';
    var options = {
      key: fs.readFileSync(key),
      cert: fs.readFileSync(cert)
    };
    this._webServer = https.createServer(options, function (req, res) {
       self._requestListener.call(self, req, res);
    });
  } else { // HTTP Server
    this._webServer = http.createServer(function (req, res) {
      self._requestListener.call(self, req, res);
    });
  }

  this._webServer.listen(port, host, function () {
    console.log(protocol+" WebHook listening on:", port);
  });
};

TelegramBot.prototype._requestListener = function (req, res) {
  var self = this;
  var url = '/bot'+this.token;
  if (req.url === url && req.method === 'POST') {
    var fullBody = '';
    req.on('data', function (chunk) {
      fullBody += chunk.toString();
    });
    req.on('end', function () {
      try {
        var data = JSON.parse(fullBody);
        self.offset = data.update_id;
        self.emit('message', data.message);
      } catch (error) {
        console.error(error);
      }
      res.end('OK :P\n');
    });
  } else {
    res.end('OK\n');
  }
};

TelegramBot.prototype._processUpdates = function (updates) {
  for (var i = 0; i < updates.length; i++) {
    if (updates[i].message) {
      this.emit('message', updates[i].message);
    }
  }
};

TelegramBot.prototype._polling = function (timeout) {
  var self = this;
  this.getUpdates(timeout).then(function (data) {
    self._processUpdates(data);
    self._polling(timeout);
  });
};

TelegramBot.prototype._request = function (path, options) {
  if (!this.token) {
    throw new Error('Telegram Bot Token not provided!');
  }
  options = options || {};
  options.url = URL.format({
    protocol: 'https',
    host: 'api.telegram.org',
    pathname: '/bot'+this.token+'/'+path
  });

  return requestPromise(options)
    .then(function (resp) {
      if (resp[0].statusCode !== 200) {
        throw new Error(resp[0].statusCode+' '+resp[0].body);
      }
      var data = JSON.parse(resp[0].body);
      if (data.ok) {
        return data.result;
      } else {
        throw new Error(data.error_code+' '+data.description);
      }
    });
};

/**
 * Returns basic information about the bot in form of a `User` object.
 * @return {Promise}
 * @see
 */
TelegramBot.prototype.getMe = function () {
  var path = 'getMe';
  return this._request(path);
};

/**
 * Specify an url to receive incoming updates via an outgoing webHook.
 * @param {String} url URL where Telegram will make HTTP Post. Leave empty to
 * delete webHook.
 * @see https://core.telegram.org/bots/api#setwebhook
 */
TelegramBot.prototype.setWebHook = function (url) {
  var path = 'setWebHook';
  var qs = {url: url};
  return this._request(path, {qs: qs})
    .then(function (resp) {
      if (!resp) {
        throw new Error(resp);
      }
      return resp;
    });
};

/**
 * Use this method to receive incoming updates using long polling
 * @param  {Number|String} [timeout] Timeout in seconds for long polling.
 * @param  {Number|String} [limit] Limits the number of updates to be retrieved.
 * @param  {Number|String} [offset] Identifier of the first update to be returned.
 * @return {Promise} Updates
 * @see https://core.telegram.org/bots/api#getupdates
 */
TelegramBot.prototype.getUpdates = function (timeout, limit, offset) {
  var self = this;
  var query = {
    offset: offset || this.offset+1,
    limit: limit,
    timeout: timeout
  };

  return this._request('getUpdates', {qs: query})
    .then(function (result) {
      var last = result[result.length-1];
      if (last) {
        self.offset = last.update_id;
      }
      return result;
    });
};

/**
 * Send text message.
 * @param  {Number|String} chatId Unique identifier for the message recipient
 * @param  {Sting} text Text of the message to be sent
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendmessage
 */
TelegramBot.prototype.sendMessage = function (chatId, text, options) {
  var query = options || {};
  query.chat_id = chatId;
  query.text = text;
  return this._request('sendMessage', {qs: query});
};

/**
 * Forward messages of any kind.
 * @param  {Number|String} chatId     Unique identifier for the message recipient
 * @param  {Number|String} fromChatId Unique identifier for the chat where the
 * original message was sent
 * @param  {Number|String} messageId  Unique message identifier
 * @return {Promise}
 */
TelegramBot.prototype.forwardMessage = function (chatId, fromChatId, messageId) {
  var query = {
    chat_id: chatId,
    from_chat_id: fromChatId,
    message_id: messageId
  };
  return this._request('forwardMessage', {qs: query});
};

TelegramBot.prototype._formatSendData = function (type, data) {
  var formData;
  var fileName;
  var fileId;
  if (data instanceof stream.Stream) {
    fileName = path.basename(data.path);
    formData = {};
    formData[type] = {
      value: data,
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else if (fs.existsSync(data)) {
    fileName = path.basename(data);
    formData = {};
    formData[type] = {
      value: fs.createReadStream(data),
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else {
    fileId = data;
  }
  return [formData, fileId];
};

/**
 * Send photo
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} photo A file path or a Stream. Can
 * also be a `file_id` previously uploaded
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendphoto
 */
TelegramBot.prototype.sendPhoto = function (chatId, photo, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('photo', photo);
  opts.formData = content[0];
  opts.qs.photo = content[1];
  return this._request('sendPhoto', opts);
};

/**
 * Send audio
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} audio A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendaudio
 */
TelegramBot.prototype.sendAudio = function (chatId, audio, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('audio', audio);
  opts.formData = content[0];
  opts.qs.audio = content[1];
  return this._request('sendAudio', opts);
};

/**
 * Send Document
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendDocument
 */
TelegramBot.prototype.sendDocument = function (chatId, doc, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('document', doc);
  opts.formData = content[0];
  opts.qs.document = content[1];
  return this._request('sendDocument', opts);
};

/**
 * Send .webp stickers.
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendsticker
 */
TelegramBot.prototype.sendSticker = function (chatId, sticker, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('sticker', sticker);
  opts.formData = content[0];
  opts.qs.sticker = content[1];
  return this._request('sendSticker', opts);
};

/**
 * Send video files, Telegram clients support mp4 videos (other formats may be sent whith `sendDocument`)
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendvideo
 */
TelegramBot.prototype.sendVideo = function (chatId, video, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('video', video);
  opts.formData = content[0];
  opts.qs.video = content[1];
  return this._request('sendVideo', opts);
};

/**
 * Send chat action.
 * `typing` for text messages,
 * `upload_photo` for photos, `record_video` or `upload_video` for videos,
 * `record_audio` or `upload_audio` for audio files, `upload_document` for general files,
 * `find_location` for location data.
 *
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String} action Type of action to broadcast.
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendchataction
 */
TelegramBot.prototype.sendChatAction = function (chatId, action) {
  var query = {
    chat_id: chatId,
    action: action
  };
  return this._request('sendChatAction', {qs: query});
};

/**
 * Use this method to get a list of profile pictures for a user.
 * Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object.
 *
 * @param  {Number|String} userId  Unique identifier of the target user
 * @param  {Number} [offset] Sequential number of the first photo to be returned. By default, all photos are returned.
 * @param  {Number} [limit] Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100.
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#getuserprofilephotos
 */
TelegramBot.prototype.getUserProfilePhotos = function (userId, offset, limit) {
  var query = {
    user_id: userId,
    offset: offset,
    limit: limit
  };
  return this._request('getUserProfilePhotos', {qs: query});
};

/**
 * Send location.
 * Use this method to send point on the map.
 *
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {Float} latitude Latitude of location
 * @param  {Float} longitude Longitude of location
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendlocation
 */
TelegramBot.prototype.sendLocation = function (chatId, latitude, longitude, options) {
  var query = options || {};
  query.chat_id = chatId;
  query.latitude = latitude;
  query.longitude = longitude;
  return this._request('sendLocation', {qs: query});
};

module.exports = TelegramBot;
<commit_msg>After polling error, keep trying<commit_after>var EventEmitter = require('events').EventEmitter;
var Promise = require("bluebird");
var request = require("request");
var stream = require('stream');
var https = require('https');
var http = require('http');
var util = require('util');
var mime = require('mime');
var path = require('path');
var URL = require('url');
var fs = require('fs');

var requestPromise = Promise.promisify(request);

/**
 * Both request method to obtain messages are implemented. To use standard polling, set `polling: true`
 * on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a valid (not self signed) SSL certificate.
 * Emmits `message` when a message arrives.
 *
 * @class TelegramBot
 * @constructor
 * @param {String} token Bot Token
 * @param {Object} [options]
 * @param {Boolean|Object} [options.polling=false] Set true to enable polling
 * @param {String|Number} [options.polling.timeout=4] Polling time
 * @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook
 * @param {String} [options.webHook.key] PEM private key to webHook server
 * @param {String} [options.webHook.cert] PEM certificate key to webHook server
 * @see https://core.telegram.org/bots/api
 */
var TelegramBot = function (token, options) {
  options = options || {};
  this.token = token;
  this.offset = 0;
  this._webServer = null;

  if (options.polling) {
    // By default polling for 4 seconds
    var timeout = options.polling.timeout || 4;
    this._polling(timeout);
  }

  if (options.webHook) {
    var port = options.webHook.port || 8443;
    var key = options.webHook.key;
    var cert = options.webHook.cert;
    var host = options.webHook.host;
    this._configureWebHook(port, host, key, cert);
  }
};

util.inherits(TelegramBot, EventEmitter);

TelegramBot.prototype._configureWebHook = function (port, host, key, cert) {
  var protocol = 'HTTP';
  var self = this;

  if (key && cert) { // HTTPS Server
    protocol = 'HTTPS';
    var options = {
      key: fs.readFileSync(key),
      cert: fs.readFileSync(cert)
    };
    this._webServer = https.createServer(options, function (req, res) {
       self._requestListener.call(self, req, res);
    });
  } else { // HTTP Server
    this._webServer = http.createServer(function (req, res) {
      self._requestListener.call(self, req, res);
    });
  }

  this._webServer.listen(port, host, function () {
    console.log(protocol+" WebHook listening on:", port);
  });
};

TelegramBot.prototype._requestListener = function (req, res) {
  var self = this;
  var url = '/bot'+this.token;
  if (req.url === url && req.method === 'POST') {
    var fullBody = '';
    req.on('data', function (chunk) {
      fullBody += chunk.toString();
    });
    req.on('end', function () {
      try {
        var data = JSON.parse(fullBody);
        self.offset = data.update_id;
        self.emit('message', data.message);
      } catch (error) {
        console.error(error);
      }
      res.end('OK :P\n');
    });
  } else {
    res.end('OK\n');
  }
};

TelegramBot.prototype._processUpdates = function (updates) {
  for (var i = 0; i < updates.length; i++) {
    if (updates[i].message) {
      this.emit('message', updates[i].message);
    }
  }
};

TelegramBot.prototype._polling = function (timeout) {
  var self = this;
  this.getUpdates(timeout).then(function (data) {
    self._processUpdates(data);
    self._polling(timeout);
  }).catch(function (err) {
    // console.error(err);
    // Wait for 2 seconds before retry
    setTimeout(self._polling.bind(self), 2000, timeout);
  });
};

TelegramBot.prototype._request = function (path, options) {
  if (!this.token) {
    throw new Error('Telegram Bot Token not provided!');
  }
  options = options || {};
  options.url = URL.format({
    protocol: 'https',
    host: 'api.telegram.org',
    pathname: '/bot'+this.token+'/'+path
  });

  return requestPromise(options)
    .then(function (resp) {
      if (resp[0].statusCode !== 200) {
        throw new Error(resp[0].statusCode+' '+resp[0].body);
      }
      var data = JSON.parse(resp[0].body);
      if (data.ok) {
        return data.result;
      } else {
        throw new Error(data.error_code+' '+data.description);
      }
    });
};

/**
 * Returns basic information about the bot in form of a `User` object.
 * @return {Promise}
 * @see
 */
TelegramBot.prototype.getMe = function () {
  var path = 'getMe';
  return this._request(path);
};

/**
 * Specify an url to receive incoming updates via an outgoing webHook.
 * @param {String} url URL where Telegram will make HTTP Post. Leave empty to
 * delete webHook.
 * @see https://core.telegram.org/bots/api#setwebhook
 */
TelegramBot.prototype.setWebHook = function (url) {
  var path = 'setWebHook';
  var qs = {url: url};
  return this._request(path, {qs: qs})
    .then(function (resp) {
      if (!resp) {
        throw new Error(resp);
      }
      return resp;
    });
};

/**
 * Use this method to receive incoming updates using long polling
 * @param  {Number|String} [timeout] Timeout in seconds for long polling.
 * @param  {Number|String} [limit] Limits the number of updates to be retrieved.
 * @param  {Number|String} [offset] Identifier of the first update to be returned.
 * @return {Promise} Updates
 * @see https://core.telegram.org/bots/api#getupdates
 */
TelegramBot.prototype.getUpdates = function (timeout, limit, offset) {
  var self = this;
  var query = {
    offset: offset || this.offset+1,
    limit: limit,
    timeout: timeout
  };

  return this._request('getUpdates', {qs: query})
    .then(function (result) {
      var last = result[result.length-1];
      if (last) {
        self.offset = last.update_id;
      }
      return result;
    });
};

/**
 * Send text message.
 * @param  {Number|String} chatId Unique identifier for the message recipient
 * @param  {Sting} text Text of the message to be sent
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendmessage
 */
TelegramBot.prototype.sendMessage = function (chatId, text, options) {
  var query = options || {};
  query.chat_id = chatId;
  query.text = text;
  return this._request('sendMessage', {qs: query});
};

/**
 * Forward messages of any kind.
 * @param  {Number|String} chatId     Unique identifier for the message recipient
 * @param  {Number|String} fromChatId Unique identifier for the chat where the
 * original message was sent
 * @param  {Number|String} messageId  Unique message identifier
 * @return {Promise}
 */
TelegramBot.prototype.forwardMessage = function (chatId, fromChatId, messageId) {
  var query = {
    chat_id: chatId,
    from_chat_id: fromChatId,
    message_id: messageId
  };
  return this._request('forwardMessage', {qs: query});
};

TelegramBot.prototype._formatSendData = function (type, data) {
  var formData;
  var fileName;
  var fileId;
  if (data instanceof stream.Stream) {
    fileName = path.basename(data.path);
    formData = {};
    formData[type] = {
      value: data,
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else if (fs.existsSync(data)) {
    fileName = path.basename(data);
    formData = {};
    formData[type] = {
      value: fs.createReadStream(data),
      options: {
        filename: fileName,
        contentType: mime.lookup(fileName)
      }
    };
  } else {
    fileId = data;
  }
  return [formData, fileId];
};

/**
 * Send photo
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} photo A file path or a Stream. Can
 * also be a `file_id` previously uploaded
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendphoto
 */
TelegramBot.prototype.sendPhoto = function (chatId, photo, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('photo', photo);
  opts.formData = content[0];
  opts.qs.photo = content[1];
  return this._request('sendPhoto', opts);
};

/**
 * Send audio
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} audio A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendaudio
 */
TelegramBot.prototype.sendAudio = function (chatId, audio, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('audio', audio);
  opts.formData = content[0];
  opts.qs.audio = content[1];
  return this._request('sendAudio', opts);
};

/**
 * Send Document
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendDocument
 */
TelegramBot.prototype.sendDocument = function (chatId, doc, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('document', doc);
  opts.formData = content[0];
  opts.qs.document = content[1];
  return this._request('sendDocument', opts);
};

/**
 * Send .webp stickers.
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendsticker
 */
TelegramBot.prototype.sendSticker = function (chatId, sticker, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('sticker', sticker);
  opts.formData = content[0];
  opts.qs.sticker = content[1];
  return this._request('sendSticker', opts);
};

/**
 * Send video files, Telegram clients support mp4 videos (other formats may be sent whith `sendDocument`)
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String|stream.Stream} A file path or a Stream. Can
 * also be a `file_id` previously uploaded.
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendvideo
 */
TelegramBot.prototype.sendVideo = function (chatId, video, options) {
  var opts = {
    qs: options || {}
  };
  opts.qs.chat_id = chatId;
  var content = this._formatSendData('video', video);
  opts.formData = content[0];
  opts.qs.video = content[1];
  return this._request('sendVideo', opts);
};

/**
 * Send chat action.
 * `typing` for text messages,
 * `upload_photo` for photos, `record_video` or `upload_video` for videos,
 * `record_audio` or `upload_audio` for audio files, `upload_document` for general files,
 * `find_location` for location data.
 *
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {String} action Type of action to broadcast.
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendchataction
 */
TelegramBot.prototype.sendChatAction = function (chatId, action) {
  var query = {
    chat_id: chatId,
    action: action
  };
  return this._request('sendChatAction', {qs: query});
};

/**
 * Use this method to get a list of profile pictures for a user.
 * Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object.
 *
 * @param  {Number|String} userId  Unique identifier of the target user
 * @param  {Number} [offset] Sequential number of the first photo to be returned. By default, all photos are returned.
 * @param  {Number} [limit] Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100.
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#getuserprofilephotos
 */
TelegramBot.prototype.getUserProfilePhotos = function (userId, offset, limit) {
  var query = {
    user_id: userId,
    offset: offset,
    limit: limit
  };
  return this._request('getUserProfilePhotos', {qs: query});
};

/**
 * Send location.
 * Use this method to send point on the map.
 *
 * @param  {Number|String} chatId  Unique identifier for the message recipient
 * @param  {Float} latitude Latitude of location
 * @param  {Float} longitude Longitude of location
 * @param  {Object} [options] Additional Telegram query options
 * @return {Promise}
 * @see https://core.telegram.org/bots/api#sendlocation
 */
TelegramBot.prototype.sendLocation = function (chatId, latitude, longitude, options) {
  var query = options || {};
  query.chat_id = chatId;
  query.latitude = latitude;
  query.longitude = longitude;
  return this._request('sendLocation', {qs: query});
};

module.exports = TelegramBot;
<|endoftext|>