<commit_before>const request = require('supertest');
const app = require('../app');
describe('name to point', function () {
  it('should return JSON object with geolocation',
      function (done) {
        request(app)
          .get('/point?name=OldCity&lat=53.66&lon=23.83')
          .expect(200)
          .expect({
            lat: '53.70177645',
            lon: '23.8347894179425',
            display_name: 'OldCity, 17, улица Дубко, Девятовка, Ленинский район,' +
            ' Гродно, Гродненская область, 230012, Беларусь',
          })
          .end(function (err, res) {
            if (err) {
              return done(err);
            }
            done();
          });
      });
  it('should return an error',
    function (done) {
      request(app)
        .get('/point?name=NONAME&lat=53.66&lon=23.83')
        .expect(404)
        .end(function (err, res) {
          if (err) {
            return done(err);
          }
          done();
        });
    });
});
<commit_msg>Fix name of test<commit_after>const request = require('supertest');
const app = require('../app');
describe('name to point', function () {
  it('should return JSON object with geolocation',
      function (done) {
        request(app)
          .get('/point?name=OldCity&lat=53.66&lon=23.83')
          .expect(200)
          .expect({
            lat: '53.70177645',
            lon: '23.8347894179425',
            display_name: 'OldCity, 17, улица Дубко, Девятовка, Ленинский район,' +
            ' Гродно, Гродненская область, 230012, Беларусь',
          })
          .end(function (err, res) {
            if (err) {
              return done(err);
            }
            done();
          });
      });
  it('should respond with Not Found in case of failed name resolution',
    function (done) {
      request(app)
        .get('/point?name=NONAME&lat=53.66&lon=23.83')
        .expect(404)
        .end(function (err, res) {
          if (err) {
            return done(err);
          }
          done();
        });
    });
});
<|endoftext|>


<commit_before>var browser = browser || undefined;
var chrome = browser || chrome;

// Control page action
var fbUrlRegExp = new RegExp("^(http://|https://).*\.facebook\.com/");
var checkFbUrl = function (tabId, changeInfo, tab) {
    if (fbUrlRegExp.test(tab.url)) {
        chrome.pageAction.show(tabId);
    }
};

chrome.tabs.onUpdated.addListener(checkFbUrl);

// Google analytics
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

//read https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#disabling_cookies for more information.
ga('create', 'UA-3607701-10', {'storage': 'none'});
//read https://code.google.com/p/analytics-issues/issues/detail?id=312 for more information.
ga('set','checkProtocolTask', null);
ga('send', 'pageview');
var manifest = chrome.runtime.getManifest();
ga('send', 'event', 'ChromeExtVersion',manifest.version);

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
    //console.log("get message");
    //console.log(request);
    //console.log(sender);
    //console.log(sendResponse);
    if (request.request == "i13n") {
        var event = request.event;
        if (event == "QCLeanDidLoad") {
            ga('send', 'event', event, manifest.version);
        } else if (event == "CannotHideTargetElement") {
            ga('send', 'event', event, request.type, manifest.version);
        } else if (event == "CollaspeDidTapped") {
            ga('send', 'event', event, manifest.version);
        }
    }
});
<commit_msg>generate ramdom anonymous client id<commit_after>var browser = browser || chrome;

/* control page action */
let fbUrlRegExp = new RegExp("^(http://|https://).*\.facebook\.com/");
let checkFbUrl = (tabId, changeInfo, tab) => {
    if (fbUrlRegExp.test(tab.url)) {
        browser.pageAction.show(tabId);
    }
};

browser.tabs.onUpdated.addListener(checkFbUrl);

/* prepare tracking constant */
let tracker = undefined;
console.log(test);
browser.storage.local.get({'qclean-anonymous-client-id': ''}, (items) => {
    let anonymousClientId = items['qclean-anonymous-client-id'];
    if (anonymousClientId.length != 16) {
        anonymousClientId = ('0000000000000000' + Math.floor(Number.MAX_SAFE_INTEGER * Math.random()).toString(16)).substr(-16);
        browser.storage.local.set({'qclean-anonymous-client-id': anonymousClientId}, () => {
            console.log(`set ${anonymousClientId} as anonymous client id`);
        });
    }
    console.log(`clientId = ${anonymousClientId}`);
});

// Google analytics
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

//read https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id#disabling_cookies for more information.
ga('create', 'UA-3607701-10', {'storage': 'none'});
//read https://code.google.com/p/analytics-issues/issues/detail?id=312 for more information.
ga('set','checkProtocolTask', null);
ga('send', 'pageview');
var manifest = chrome.runtime.getManifest();
ga('send', 'event', 'ChromeExtVersion',manifest.version);

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
    //console.log("get message");
    //console.log(request);
    //console.log(sender);
    //console.log(sendResponse);
    if (request.request == "i13n") {
        var event = request.event;
        if (event == "QCLeanDidLoad") {
            ga('send', 'event', event, manifest.version);
        } else if (event == "CannotHideTargetElement") {
            ga('send', 'event', event, request.type, manifest.version);
        } else if (event == "CollaspeDidTapped") {
            ga('send', 'event', event, manifest.version);
        }
    }
});
<|endoftext|>


<commit_before>// Reusable filter bar module
//
// usage: $('#filter-bar').filterBar(options)
// 		the options should include:
//			items: a list of items in the order they should be displayed (e.g., reverse chronological)
//			categories: a list of categories in the order they should be displayed in the sidebar
//			groupsForCategory: a dictionary of grouped items for each category
//				for example, {"category": [{"name": "group1", "items", [item1, item2, item3]}]}
//			passesFilter: a function that returns true if the item passes the filter value and false if not
//			displayGroupHeader: a function that formats the group header for display, and returns the html that should be appended
//			displayItem: a function that formats the item for display, and returns the html that should be appended
//			afterDisplay: an optional function that is called after initialization or after the filter is updated
//
// 		if you need to re-apply the filter or select the category, you can call
//			$('#filter-bar').applyFilter(category)
//		where category is an optional category name from those defined in the initial filterBar call

(function($) {
    var filterBar, currCategory, settings;
    var oldfilter=".";

    // debounce so filtering doesn't happen every millisecond
    function debounce( fn, threshold ) {
	console.log("Debouncing");
	var timeout;
	return function debounced() {
	    if ( timeout ) {
		clearTimeout( timeout );
	    }
	    function delayed() {
		fn();
		timeout = null;
	    }
	    timeout = setTimeout( delayed, threshold || 100 );
	}
    }

	$.fn.filterBar = function(options) {

		// save a reference to "this" so that we can refer to it in the event handlers below
	    filterBar = this;

		// This is the easiest way to have default options.
            settings = $.extend({
		// These are the defaults.
		items: [],
		categories: ["None"],
		groupsForCategory: {"None": []},
		passesFilter: function(item, filter) { return true; },
		displayGroupHeader: function(group) { return group.toString(); },
		displayItem: function(item) { return item.toString(); },
		afterDisplay: function() { return; }
            }, options );

            currCategory = settings.categories[0];

	    // append filter bar content
	    filterBar.append("
FILTER
<input class=\"shortTextbox\" id=\"filter-textbox\" type=\"text\" value=\"\" />
GROUP BY
");
	    $("#filter-textbox").autocomplete({
		source: settings.keywords
	    });
	    categoryList = $(document.createElement("div"));
	    categoryList.addClass("filter-bar-categories");
	    $(settings.categories).each(function() {
		var categoryItem = $(document.createElement("li"));
		var categoryText = this;
		categoryItem.addClass("filter-category");
		categoryItem.attr("id", "filter-category-" + categoryText.toLowerCase().replace(new RegExp(" "), "-"));
		categoryItem.click(function() { debounce(filterBar.applyFilter(categoryText), 1000); });
			categoryItem.text(categoryText);
		categoryList.append(categoryItem);
	    });
	    filterBar.append(categoryList);

	    filterBar.append("

");

	    // update the filtered items whenever the filter textbox changes
	    // note: it's not enough just to bind to keyup, since there are other
		//       ways for the text to change
	    $("#filter-textbox").on("propertychange change keyup paste input", function(){
		debounce(filterBar.applyTextFilter(), 500);
	    });
	    $("#filter-textbox-backup").on("propertychange change keyup paste input", function(){
		debounce(filterBar.applyTextFilter(), 500);
	    });

	    return this;
	};

	$.fn.cleanName = function(name) {
		return name.toLowerCase().replace(new RegExp(" ", "g"), "-");
	}

	$.fn.applyFilter = function(newCategory) {
	    if(newCategory) currCategory = newCategory;
	    var filter = $("#filter-textbox").val().toLowerCase();
		$(".filter-category").removeClass("filter-selected");
		$("#filter-category-" + this.cleanName(currCategory)).addClass("filter-selected");

		var groupList = $("#filter-bar-groups");
		if(settings.groupsForCategory[currCategory].length <= 1) {
			groupList.css("display", "none");
		} else {
			groupList.css("display", "block");
			var data = "
" + currCategory.toUpperCase() + "
\n"
			for(var i=0; i<settings.groupsForCategory[currCategory].length; i++) {
				data += "
" + settings.groupsForCategory[currCategory][i].name + " (" + settings.groupsForCategory[currCategory][i].items.length + ")
\n";
			}
			groupList[0].innerHTML = data;
		}

		$('#fixed-side-bar').resizeSideBar();

		var content = $("#main-content")[0];
		var data = "";
		settings.groupsForCategory[currCategory].forEach(function (group, groupIndex, groupArray) {
			var groupCount = 0;
			group.items.forEach(function(item, itemIndex, itemArray) { if(settings.passesFilter(item, filter)) groupCount++; });
			if(groupCount == 0) return;

			data += settings.displayGroupHeader(group.name);
			group.items.forEach(function (item, itemIndex, itemArray) {
				if(!settings.passesFilter(item, filter)) return;
				data += settings.displayItem(item, filter);
			});
		});
	    content.innerHTML = data;
	    settings.afterDisplay();
	}

    function checkFilter(groups, title, filter, groupPasses){
	var res=false;
	groups.forEach(function(group, groupIndex, groupArray){
	    group.items.forEach(function(item, itemIndex, itemArray){
		if(item['title'].trim()==title.trim()){
		    if(settings.passesFilter(item, filter)){
			res=true;
			groupPasses[group['name']]++;
		    }
		    else{
			res=false;
		    }
		}
	    });
	});
	return res;
    }

    // adds html markup to the specified text wherever it matches the filter, applying the highlight style
    function addHighlight(text, filter) {
	//console.log(text);
	var result = text;
	if(filter && filter.length > 0)
	    result = text.replace(new RegExp('(' + filter + ')', 'gi'), "$1");
	//console.log(result);
	return result;
    }

    function removeHighlight(text){
	text.replace(new RegExp('(*)', 'gi'), "");
	return text;
    }

    function resetHTML($template){
	$template.find('.publication-keywords').children().each(function(){
	    $(this).html(removeHighlight($(this).html()));
	});
    }

    $.fn.applyTextFilter = function(){
	var filter= $("#filter-textbox").val().toLowerCase() || $("#filter-textbox-backup").val().toLowerCase();
	var groups=settings.groupsForCategory[currCategory];
	var groupPasses={};
	groups.forEach(function(group, groupIndex, groupArray){
	    groupPasses[group['name']]=0;
	});
	if(oldfilter!=filter){
	    $('.publication-template').each(function(){
		var title = $(this).find('.publication-title').text();
		console.log(title);
		title=title.replace(/(<([^>]+)>)/ig,"");
		var passes=checkFilter(groups, title, filter, groupPasses);
		console.log(passes);
		if(!passes){
		    $(this).fadeOut();
		    //resetHTML($(this));
		}
		else{
		    $(this).fadeIn();
		    $(this).find('.publication-keywords').children().each(function(){
		    	$(this).html(addHighlight($(this).text(), filter));
		    });
		     $(this).find('.publication-authors').children().each(function(){
		    	$(this).html(addHighlight($(this).text(), filter));
		    });
		}
	    });
	    $('.talk-template').each(function(){
		var title = $(this).find('.talk-title').text();
		var passes=checkFilter(groups, title, filter, groupPasses);
		if(!passes){
		    $(this).fadeOut();
		}
		else{
		    $(this).fadeIn();
		    $(this).find('.talk-speakers').children().each(function(){
		    	$(this).html(addHighlight($(this).text(), filter));
		    });
		}
	    });
	    for(var key in groupPasses){
		if(groupPasses[key]==0){
		    $('h1[name='+key+']').fadeOut();
		}
		else{
		    $('h1[name='+key+']').fadeIn();
		}
	    }
	    oldfilter=filter;
	}

    }

}(jQuery));
<commit_msg>Fixed conflicts with master (again)<commit_after>// Reusable filter bar module
//
// usage: $('#filter-bar').filterBar(options)
// 		the options should include:
//			items: a list of items in the order they should be displayed (e.g., reverse chronological)
//			categories: a list of categories in the order they should be displayed in the sidebar
//			groupsForCategory: a dictionary of grouped items for each category
//				for example, {"category": [{"name": "group1", "items", [item1, item2, item3]}]}
//			passesFilter: a function that returns true if the item passes the filter value and false if not
//			displayGroupHeader: a function that formats the group header for display, and returns the html that should be appended
//			displayItem: a function that formats the item for display, and returns the html that should be appended
//			afterDisplay: an optional function that is called after initialization or after the filter is updated
//
// 		if you need to re-apply the filter or select the category, you can call
//			$('#filter-bar').applyFilter(category)
//		where category is an optional category name from those defined in the initial filterBar call

(function($) {
    var filterBar, currCategory, settings;
    var oldfilter=".";

    // debounce so filtering doesn't happen every millisecond
    function debounce( fn, threshold ) {
	console.log("Debouncing");
	var timeout;
	return function debounced() {
	    if ( timeout ) {
		clearTimeout( timeout );
	    }
	    function delayed() {
		fn();
		timeout = null;
	    }
	    timeout = setTimeout( delayed, threshold || 100 );
	}
    }

	$.fn.filterBar = function(options) {

		// save a reference to "this" so that we can refer to it in the event handlers below
	    filterBar = this;

		// This is the easiest way to have default options.
            settings = $.extend({
		// These are the defaults.
		items: [],
		categories: ["None"],
		groupsForCategory: {"None": []},
		passesFilter: function(item, filter) { return true; },
		displayGroupHeader: function(group) { return group.toString(); },
		displayItem: function(item) { return item.toString(); },
		afterDisplay: function() { return; }
            }, options );

            currCategory = settings.categories[0];

	    // append filter bar content
	    filterBar.append("
FILTER
<input class=\"shortTextbox\" id=\"filter-textbox\" type=\"text\" value=\"\" />
GROUP BY
");
	    $("#filter-textbox").autocomplete({
		source: settings.keywords
	    });
	    categoryList = $(document.createElement("div"));
	    categoryList.addClass("filter-bar-categories");
	    $(settings.categories).each(function() {
		var categoryItem = $(document.createElement("li"));
		var categoryText = this;
		categoryItem.addClass("filter-category");
		categoryItem.attr("id", "filter-category-" + categoryText.toLowerCase().replace(new RegExp(" "), "-"));
		categoryItem.click(function() { debounce(filterBar.applyFilter(categoryText), 1000); });
			categoryItem.text(categoryText);
		categoryList.append(categoryItem);
	    });
	    filterBar.append(categoryList);

	    filterBar.append("

");

	    // update the filtered items whenever the filter textbox changes
	    // note: it's not enough just to bind to keyup, since there are other
		//       ways for the text to change
	    $("#filter-textbox").on("propertychange change keyup paste input", function(){
		debounce(filterBar.applyTextFilter(), 500);
	    });
	    $("#filter-textbox-backup").on("propertychange change keyup paste input", function(){
		debounce(filterBar.applyTextFilter(), 500);
	    });

	    return this;

	};

	$.fn.cleanName = function(name) {
		return name.toLowerCase().replace(new RegExp(" ", "g"), "-");
	}

	$.fn.applyFilter = function(newCategory) {
	    if(newCategory) currCategory = newCategory;
	    var filter = $("#filter-textbox").val().toLowerCase() || $("#filter-textbox-backup").val().toLowerCase();
		$(".filter-category").removeClass("filter-selected");
		$("#filter-category-" + this.cleanName(currCategory)).addClass("filter-selected");

		var groupList = $("#filter-bar-groups");
		if(settings.groupsForCategory[currCategory].length <= 1) {
			groupList.css("display", "none");
		} else {
			groupList.css("display", "block");
			var data = "
" + currCategory.toUpperCase() + "
\n"
			for(var i=0; i<settings.groupsForCategory[currCategory].length; i++) {
				data += "
" + settings.groupsForCategory[currCategory][i].name + " (" + settings.groupsForCategory[currCategory][i].items.length + ")
\n";
			}
			groupList[0].innerHTML = data;
		}

		$('#fixed-side-bar').resizeSideBar();

		var content = $("#main-content")[0];
		var data = "";
		settings.groupsForCategory[currCategory].forEach(function (group, groupIndex, groupArray) {
			var groupCount = 0;
			group.items.forEach(function(item, itemIndex, itemArray) { if(settings.passesFilter(item, filter)) groupCount++; });
			if(groupCount == 0) return;

			data += settings.displayGroupHeader(group.name);
			group.items.forEach(function (item, itemIndex, itemArray) {
				if(!settings.passesFilter(item, filter)) return;
				data += settings.displayItem(item, filter);
			});
		});
	    content.innerHTML = data;
	    settings.afterDisplay();
	}

    function checkFilter(groups, title, filter, groupPasses){
	var res=false;
	groups.forEach(function(group, groupIndex, groupArray){
	    group.items.forEach(function(item, itemIndex, itemArray){
		if(item['title'].trim()==title.trim()){
		    if(settings.passesFilter(item, filter)){
			res=true;
			groupPasses[group['name']]++;
		    }
		    else{
			res=false;
		    }
		}
	    });
	});
	return res;
    }

    // adds html markup to the specified text wherever it matches the filter, applying the highlight style
    function addHighlight(text, filter) {
	//console.log(text);
	var result = text;
	if(filter && filter.length > 0)
	    result = text.replace(new RegExp('(' + filter + ')', 'gi'), "$1");
	//console.log(result);
	return result;
    }

    function removeHighlight(text){
	text.replace(new RegExp('(*)', 'gi'), "");
	return text;
    }

    function resetHTML($template){
	$template.find('.publication-keywords').children().each(function(){
	    $(this).html(removeHighlight($(this).html()));
	});
    }

    $.fn.applyTextFilter = function(){
	var filter= $("#filter-textbox").val().toLowerCase() || $("#filter-textbox-backup").val().toLowerCase();
	var groups=settings.groupsForCategory[currCategory];
	var groupPasses={};
	groups.forEach(function(group, groupIndex, groupArray){
	    groupPasses[group['name']]=0;
	});
	if(oldfilter!=filter){
	    $('.publication-template').each(function(){
		var title = $(this).find('.publication-title').text();
		console.log(title);
		title=title.replace(/(<([^>]+)>)/ig,"");
		var passes=checkFilter(groups, title, filter, groupPasses);
		console.log(passes);
		if(!passes){
		    $(this).fadeOut();
		    //resetHTML($(this));
		}
		else{
		    $(this).fadeIn();
		    $(this).find('.publication-keywords').children().each(function(){
		    	$(this).html(addHighlight($(this).text(), filter));
		    });
		     $(this).find('.publication-authors').children().each(function(){
		    	$(this).html(addHighlight($(this).text(), filter));
		    });
		}
	    });
	    $('.talk-template').each(function(){
		var title = $(this).find('.talk-title').text();
		var passes=checkFilter(groups, title, filter, groupPasses);
		if(!passes){
		    $(this).fadeOut();
		}
		else{
		    $(this).fadeIn();
		    $(this).find('.talk-speakers').children().each(function(){
		    	$(this).html(addHighlight($(this).text(), filter));
		    });
		}
	    });
	    for(var key in groupPasses){
		if(groupPasses[key]==0){
		    $('h1[name='+key+']').fadeOut();
		}
		else{
		    $('h1[name='+key+']').fadeIn();
		}
	    }
	    oldfilter=filter;
	}

    }

}(jQuery));
<|endoftext|>


<commit_before>/*global describe, it, expect, require */
'use strict';
var parse = require('../../lib/twilio/parse');
const qs = require('querystring');

describe('Twilio parse', () => {
  it('returns nothing if the format is invalid', () => {
    expect(parse(qs.stringify('string'))).toBeUndefined();
    expect(parse()).toBeUndefined();
    expect(parse(qs.stringify(false))).toBeUndefined();
    expect(parse(qs.stringify(123))).toBeUndefined();
    expect(parse(qs.stringify({}))).toBeUndefined();
    expect(parse(qs.stringify([1, 2, 3]))).toBeUndefined();
  });
  it('returns nothing if the Body is undefined or missing', () => {
    expect(parse(qs.stringify({From: '+3333333333'}))).toBeUndefined();
    expect(parse(qs.stringify({From: '+3333333333', Body: undefined}))).toBeUndefined();
  });
  it('returns nothing if the From is undefined or missing', () => {
    expect(parse(qs.stringify({Body: 'SMS Twilio'}))).toBeUndefined();
    expect(parse(qs.stringify({From: undefined, Body: 'SMS Twilio'}))).toBeUndefined();
  });
  it('returns a parsed object when Body and From are present', () => {
    var msg = qs.stringify({From: '+3333333333', Body: 'SMS Twilio'});
    expect(parse(msg)).toEqual({ sender: '+3333333333', text: 'SMS Twilio', originalRequest: qs.parse(msg), type: 'twilio'});
  });
});
<commit_msg>add test for parsing Twilio MMS<commit_after>/*global describe, it, expect, require */
'use strict';
var parse = require('../../lib/twilio/parse');
const qs = require('querystring');

describe('Twilio parse', () => {
  it('returns nothing if the format is invalid', () => {
    expect(parse(qs.stringify('string'))).toBeUndefined();
    expect(parse()).toBeUndefined();
    expect(parse(qs.stringify(false))).toBeUndefined();
    expect(parse(qs.stringify(123))).toBeUndefined();
    expect(parse(qs.stringify({}))).toBeUndefined();
    expect(parse(qs.stringify([1, 2, 3]))).toBeUndefined();
  });
  it('returns nothing if the Body is undefined or missing', () => {
    expect(parse(qs.stringify({From: '+3333333333'}))).toBeUndefined();
    expect(parse(qs.stringify({From: '+3333333333', Body: undefined}))).toBeUndefined();
  });
  it('returns nothing if the From is undefined or missing', () => {
    expect(parse(qs.stringify({Body: 'SMS Twilio'}))).toBeUndefined();
    expect(parse(qs.stringify({From: undefined, Body: 'SMS Twilio'}))).toBeUndefined();
  });
  it('returns a parsed object when Body and From are present', () => {
    var msg = qs.stringify({From: '+3333333333', Body: 'SMS Twilio'});
    expect(parse(msg)).toEqual({ sender: '+3333333333', text: 'SMS Twilio', originalRequest: qs.parse(msg), type: 'twilio'});
  });
  it('returns a parsed object when From is present and MMS attachments exist', () => {
    var msg = qs.stringify({From: '+3333333333', NumMedia: '1', MediaContentType0: 'image/jpeg', MediaUrl0: 'https://api.twilio.com/test'});
    expect(parse(msg)).toEqual({
      sender: '+3333333333',
      text: undefined,
      originalRequest: qs.parse(msg),
      type: 'twilio',
      media: [{ contentType: 'image/jpeg', url: 'https://api.twilio.com/test' }]
    });
  });
});
<|endoftext|>


<commit_before>
var expect = require('chai').expect
var DynamoDB = require('aws-dynamodb')()

describe('describeTable', function () {
    it('should throw error on inexistent table', function(done) { // added "done" as parameter
		DynamoDB
			.client
			.describeTable({
				TableName: 'inexistent-table'
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    });

    it('should return table data', function(done) {
		DynamoDB
			.client
			.describeTable({
				TableName: 'hash_range'
			}, function(err, data) {
				if (err)
					throw err
				else {
					expect(data).to.have.property('Table')
					expect(data.Table).to.have.property('KeySchema')
					done()
				}
			})
    })
})

describe('insert', function () {
    it('should fail if missing RANGE', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 'hash1'
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })
    it('should fail if missing HASH', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				range: 1
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })
    it('should fail if HASH is wrong type', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 1,
				range: 1
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })
    it('should fail if RANGE is wrong type', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 'hash1',
				range: 'xxx'
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })

    it('should fail if GSI RANGE is wrong type', function(done) {
		DynamoDB
			.table('hash_range')
			.where('hash').eq('hash1')
			.where('range').eq(1)
			.delete(function( err, data ) {
				DynamoDB
					table('hash_range')
					.insert({
						hash: 'hash1',
						range: 1,
						gsi_range: 1
					}, function(err, data) {
						if (err)
							done()
						else
							throw err
					})
			})
    })

    it('should insert when item does not exist', function(done) {
		DynamoDB
			.table('hash_range')
			.where('hash').eq('hash1')
			.where('range').eq(1)
			.delete(function( err, data ) {

				DynamoDB
					table('hash_range')
					.insert({
						hash: 'hash1',
						range: 1,
						gsi_range: 'a'
					}, function(err, data) {
						if (err)
							throw err
						else
							DynamoDB
								table('hash_range')
								.insert({
									hash: 'hash1',
									range: 2
								}, function(err, data) {
									// is ok if it fails since this would be a duplicate when executing 2nd time
									// we just want this item present in the database
									done()
								})

					})

			})
    })

    it('should fail when item already exists', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 'hash1',
				range: 1
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})

})

describe('scan', function () {
    it('should fail when table name is wrong', function(done) {
		DynamoDB
			.table('inexistent-table')
			.scan( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})

    it('should return 2 items', function(done) {
		DynamoDB
			.table('hash_range')
			.scan( function(err, data) {
				if (err)
					throw err
				else {
					if (data.length !== 2)
						throw 'should be length: 2'
					else
						done()
				}

			})
	})
})

describe('GSI scan', function () {
    it('should fail when index name is wrong', function(done) {
		DynamoDB
			.table('inexistent-table')
			.index('gsi_index')
			.scan( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})

    it('should return 1 item', function(done) {
		DynamoDB
			.table('hash_range')
			.index('gsi_index')
			.scan( function(err, data) {
				if (err)
					throw err
				else {
					if (data.length !== 1)
						throw 'should be length: 1 but is ' + data.length
					else
						done()
				}

			})
	})
})

// @todo: update, scan, replace, query, query lsi, query gsi, delete item, delete item attributes, create table
<commit_msg>unit testing on query()<commit_after>
var expect = require('chai').expect
var DynamoDB = require('aws-dynamodb')()

describe('describeTable', function () {
    it('should throw error on inexistent table', function(done) { // added "done" as parameter
		DynamoDB
			.client
			.describeTable({
				TableName: 'inexistent-table'
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    });

    it('should return table data', function(done) {
		DynamoDB
			.client
			.describeTable({
				TableName: 'hash_range'
			}, function(err, data) {
				if (err)
					throw err
				else {
					expect(data).to.have.property('Table')
					expect(data.Table).to.have.property('KeySchema')
					done()
				}
			})
    })
})

describe('insert', function () {
    it('should fail if missing RANGE', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 'hash1'
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })
    it('should fail if missing HASH', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				range: 1
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })
    it('should fail if HASH is wrong type', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 1,
				range: 1
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })
    it('should fail if RANGE is wrong type', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 'hash1',
				range: 'xxx'
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
    })

    it('should fail if GSI RANGE is wrong type', function(done) {
		DynamoDB
			.table('hash_range')
			.where('hash').eq('hash1')
			.where('range').eq(1)
			.delete(function( err, data ) {
				DynamoDB
					table('hash_range')
					.insert({
						hash: 'hash1',
						range: 1,
						gsi_range: 1
					}, function(err, data) {
						if (err)
							done()
						else
							throw err
					})
			})
    })

    it('should insert when item does not exist', function(done) {
		DynamoDB
			.table('hash_range')
			.where('hash').eq('hash1')
			.where('range').eq(1)
			.delete(function( err, data ) {

				DynamoDB
					table('hash_range')
					.insert({
						hash: 'hash1',
						range: 1,
						gsi_range: 'a'
					}, function(err, data) {
						if (err)
							throw err
						else
							DynamoDB
								table('hash_range')
								.insert({
									hash: 'hash1',
									range: 2
								}, function(err, data) {
									// is ok if it fails since this would be a duplicate when executing 2nd time
									// we just want this item present in the database
									done()
								})

					})

			})
    })

    it('should fail when item already exists', function(done) {
		DynamoDB
			table('hash_range')
			.insert({
				hash: 'hash1',
				range: 1
			}, function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})

})
describe('query', function () {
    it('should fail when table name is wrong', function(done) {
		DynamoDB
			.table('inexistent-table')
			.query( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})
    it('should fail when no .where() is specified', function(done) {
		DynamoDB
			.table('hash_range')
			.query( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})
    it('should fail when HASH has wrong type', function(done) {
		DynamoDB
			.table('hash_range')
			.where('hash').eq(5)
			.query( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})
    it('should fail when querying without HASH .eq()', function(done) {
		DynamoDB
			.table('hash_range')
			.where('hash').gt('aaa')
			.query( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})
})

describe('scan', function () {
    it('should fail when table name is wrong', function(done) {
		DynamoDB
			.table('inexistent-table')
			.scan( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})

    it('should return 2 items', function(done) {
		DynamoDB
			.table('hash_range')
			.scan( function(err, data) {
				if (err)
					throw err
				else {
					if (data.length !== 2)
						throw 'should be length: 2'
					else
						done()
				}

			})
	})
})

describe('GSI scan', function () {
    it('should fail when index name is wrong', function(done) {
		DynamoDB
			.table('inexistent-table')
			.index('gsi_index')
			.scan( function(err, data) {
				if (err)
					done()
				else
					throw err
			})
	})

    it('should return 1 item', function(done) {
		DynamoDB
			.table('hash_range')
			.index('gsi_index')
			.scan( function(err, data) {
				if (err)
					throw err
				else {
					if (data.length !== 1)
						throw 'should be length: 1 but is ' + data.length
					else
						done()
				}

			})
	})
})

// @todo: update, replace, query, query lsi, query gsi, delete item, delete item attributes, create table
<|endoftext|>


<commit_before>"use strict";

const test = require("tape");

const keyStats = require("../lib/key-statistics");

test("Key statistics tests", t => {
    t.plan(5);

    keyStats.getKeyStatistics({ symbol: "IBM" }, (err, res) => {
        t.notOk(err, "check error for getting key stats");
        t.equal(Object.keys(res).length, 48, "get count");
        t.ok(isFinite(res.enterpriseValue.raw), "get key enterprise value");
    });

    keyStats.getKeyStatistics({ symbol: "IBM190118C00100000" }, (err, res) => {
        t.equal(err, "Not Found", "not found for unknown symbol");
        t.notOk(res, "no data for unknown symbol");
    });
});
<commit_msg>Fix key stats tests.<commit_after>"use strict";

const test = require("tape");

const keyStats = require("../lib/key-statistics");

test("Key statistics tests", t => {
    t.plan(5);

    keyStats.getKeyStatistics({ symbol: "IBM" }, (err, res) => {
        t.notOk(err, "check error for getting key stats");
        t.equal(Object.keys(res).length, 50, "get count");
        t.ok(isFinite(res.enterpriseValue.raw), "get key enterprise value");
    });

    keyStats.getKeyStatistics({ symbol: "IBM190118C00100000" }, (err, res) => {
        t.equal(err, "Not Found", "not found for unknown symbol");
        t.notOk(res, "no data for unknown symbol");
    });
});
<|endoftext|>


<commit_before>import chalk from 'chalk';
import debugModule from 'debug';
import program from 'commander';
import {defaultOutputHelp, errorAndExit, noCommandAndExit} from './utils';
import Jungle from '../';
import {getTagValue} from '../utils';

const debug = debugModule('jungle:cli');

const STATUS_STYLES = {
  stopped: chalk.red,
  running: chalk.green,
  '*': chalk.gray.dim
};

function coloredStatus(stateName) {
  const statusStyle = STATUS_STYLES[stateName] || STATUS_STYLES['*'];
  return statusStyle(stateName);
}

program.option('-r, --region <name>', 'Region name');
program.action(noCommandAndExit('jungle ec2'));

program.command('ls [name]')
.description('List EC2 Instances')
.action((name, options) => {
  const jungle = new Jungle(options.parent.region);
  jungle.ec2.getInstances(name).then(instances => {
    instances.forEach(i => {
      const cols = [
        getTagValue(i.Tags, 'Name') || null,
        coloredStatus(i.State.Name),
        i.InstanceId,
        i.PrivateIpAddress || null,
        i.PublicIpAddress || null
      ];
      console.log(cols.join('\t'));
    });
  }).catch(errorAndExit);
});

program.command('up <instanceId>')
.description('Start EC2 instance')
.option('--dry-run', 'dryrun')
.action((instanceId, options) => {
  debug(instanceId);
  debug(options.opts());
  const jungle = new Jungle(options.parent.region);
  jungle.ec2.startInstances([instanceId], options.dryRun).then(result => {
    const ids = result.Instances.map(i => i.InstanceId);
    debug(`starting ${ids.join(', ')}...`);
  }).catch(errorAndExit);
});

program.command('down <instanceId>')
.description('Stop EC2 instance')
.option('--dry-run', 'dryrun')
.action((instanceId, options) => {
  debug(instanceId);
  debug(options.opts());
  const jungle = new Jungle(options.parent.region);
  jungle.ec2.stopInstances([instanceId], options.dryRun).then(result => {
    const ids = result.Instances.map(i => i.InstanceId);
    debug(`starting ${ids.join(', ')}...`);
  }).catch(errorAndExit);
});

program.parse(process.argv);
defaultOutputHelp(program);
<commit_msg>feat(commands): Change format of empty value<commit_after>import chalk from 'chalk';
import debugModule from 'debug';
import program from 'commander';
import {defaultOutputHelp, errorAndExit, noCommandAndExit} from './utils';
import Jungle from '../';
import {getTagValue} from '../utils';

const debug = debugModule('jungle:cli');

const STATUS_STYLES = {
  stopped: chalk.red,
  running: chalk.green,
  '*': chalk.gray.dim
};

function coloredStatus(stateName) {
  const statusStyle = STATUS_STYLES[stateName] || STATUS_STYLES['*'];
  return statusStyle(stateName);
}

program.option('-r, --region <name>', 'Region name');
program.action(noCommandAndExit('jungle ec2'));

program.command('ls [name]')
.description('List EC2 Instances')
.action((name, options) => {
  const jungle = new Jungle(options.parent.region);
  jungle.ec2.getInstances(name).then(instances => {
    instances.forEach(i => {
      const cols = [
        getTagValue(i.Tags, 'Name') || '',
        coloredStatus(i.State.Name),
        i.InstanceId,
        i.PrivateIpAddress || '',
        i.PublicIpAddress || ''
      ];
      console.log(cols.join('\t'));
    });
  }).catch(errorAndExit);
});

program.command('up <instanceId>')
.description('Start EC2 instance')
.option('--dry-run', 'dryrun')
.action((instanceId, options) => {
  debug(instanceId);
  debug(options.opts());
  const jungle = new Jungle(options.parent.region);
  jungle.ec2.startInstances([instanceId], options.dryRun).then(result => {
    const ids = result.Instances.map(i => i.InstanceId);
    debug(`starting ${ids.join(', ')}...`);
  }).catch(errorAndExit);
});

program.command('down <instanceId>')
.description('Stop EC2 instance')
.option('--dry-run', 'dryrun')
.action((instanceId, options) => {
  debug(instanceId);
  debug(options.opts());
  const jungle = new Jungle(options.parent.region);
  jungle.ec2.stopInstances([instanceId], options.dryRun).then(result => {
    const ids = result.Instances.map(i => i.InstanceId);
    debug(`starting ${ids.join(', ')}...`);
  }).catch(errorAndExit);
});

program.parse(process.argv);
defaultOutputHelp(program);
<|endoftext|>


<commit_before>const bot = require('./../bot');
const influx = require('./../../influx');
const request = require('request-promise-native');
let ingame;
let guild;
const updateIngame = async function(){
  if(!guild && !ingame)return;
  /*
  let playing = await request('http://localhost/v0/discord/online');
  playing = JSON.parse(playing);
  */
  let members = await guild.fetchMembers();
  console.log(typeof members)
  let playing = guild.members.filterArray(function (m) {
        if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                return m;
    });
  playing = playing.map(m => m.user.id);
  console.log(playing);
  let toRemove = ingame.members.filter(function (m){
      if(!playing.includes(m.user.id))
      {
        console.log("Not playing : "+ m.user.id)
        return m;
      }
    });
  await Promise.all(toRemove.map(async function(m){
      await m.removeRole(ingame);
   }));
   await Promise.all(playing.map(async function(m){
      const member = await guild.fetchMember(m);
      if(!member.roles.get(ingame.id))
        await member.addRole(ingame);
   }));
  influx.writePoints([
          {
            measurement: 'statistics',
            fields: { count: playing.length},
            tags: {type:'ingame'}
          }
        ]).catch(console.log);
};
bot.on('ready',()=>{
    guild =  bot.guilds.get("184536578654339072");
    ingame = guild.roles.get("322233107489226764");
});
setInterval(updateIngame,5000)
/**
bot.on('presenceUpdate',async function(om,m){
    if(m.guild.id != guild.id) return;
    if (om.presence.game && om.presence.game.name)
            if (om.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.removeRole(ingame);
    if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.addRole(ingame);
});
*/
<commit_msg>update guild obj with full cache<commit_after>const bot = require('./../bot');
const influx = require('./../../influx');
const request = require('request-promise-native');
let ingame;
let guild;
const updateIngame = async function(){
  if(!guild && !ingame)return;
  /*
  let playing = await request('http://localhost/v0/discord/online');
  playing = JSON.parse(playing);
  */
  guild = await guild.fetchMembers();
  let playing = guild.members.filterArray(function (m) {
        if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                return m;
    });
  playing = playing.map(m => m.user.id);
  console.log(playing);
  let toRemove = ingame.members.filter(function (m){
      if(!playing.includes(m.user.id))
      {
        console.log("Not playing : "+ m.user.id)
        return m;
      }
    });
  await Promise.all(toRemove.map(async function(m){
      await m.removeRole(ingame);
   }));
   await Promise.all(playing.map(async function(m){
      const member = await guild.fetchMember(m);
      if(!member.roles.get(ingame.id))
        await member.addRole(ingame);
   }));
  influx.writePoints([
          {
            measurement: 'statistics',
            fields: { count: playing.length},
            tags: {type:'ingame'}
          }
        ]).catch(console.log);
};
bot.on('ready',()=>{
    guild =  bot.guilds.get("184536578654339072");
    ingame = guild.roles.get("322233107489226764");
});
setInterval(updateIngame,5000)
/**
bot.on('presenceUpdate',async function(om,m){
    if(m.guild.id != guild.id) return;
    if (om.presence.game && om.presence.game.name)
            if (om.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.removeRole(ingame);
    if (m.presence.game && m.presence.game.name)
            if (m.presence.game.name.toLowerCase().includes("battlefield 2"))
                await m.addRole(ingame);
});
*/
<|endoftext|>


<commit_before>const Discord = require("discord.js");
const config = require("./../../config.json");
const MSS = require("./../../functions/");

module.exports = function(message, client) {
	let input = message.content.replace(/\n/g, " ").split(" ");
	let sides = 6;
	let rolls = 1;
	var result = [];
	var output, sum;

	if(input[1] && input[1].startsWith("d")) {
		//Check if it's trying to roll an "n" sided die.
		sides = parseInt(input[1].substring(1).replace(/[^0-9]+/g, ''));
	} else if (input[1]){
		//Roll the dice the number of times stated
		rolls = parseInt(input[1].replace(/[^0-9]+/g, ''));
	}

	if(input[2]) {
		rolls = parseInt(input[1].replace(/[^0-9]+/g, ''));
		sides = parseInt(input[1].replace(/[^0-9]+/g, ''));
	}

	if(!rolls || !sides || rolls < 1 || sides < 2) {
		//You can't roll something with no die, no sides, less than 1 roll or with less than 2 sides.
		MSS.msg.react(message, false, "x");
	}

	if(rolls == 1) {
		output = "Rolled a " + sides + "-sided die.";
	} else {
		//Rolled 6 6-sided dice.
		output = "Rolled " + rolls + " " + sides + "-sided dice.";
	}

	for(i=0; i<rolls; i++) {
		let value = randInt(sides);
		sum += value;
		result.push(value);
	}

	var embed = new Discord.RichEmbed()
		.setTitle("MSS-Discord")
		.setAuthor("roll", "http://moustacheminer.com/mss.png")
		.setColor("#00AE86")
		.setDescription(output)
		.setFooter("MSS-Discord, " + config.MSS.version, "")
		.setTimestamp()
		.setURL("http://moustacheminer.com/")
		.addField("Die output", result)
		.addField("Total", sum);

	message.channel.sendEmbed(embed, "", { disableEveryone: true });
}

function randInt(d) {
	Math.floor(Math.random() * d) + 1
}
<commit_msg>LOG THE ERROR!!!<commit_after>const Discord = require("discord.js");
const config = require("./../../config.json");
const MSS = require("./../../functions/");

module.exports = function(message, client) {
	let input = message.content.replace(/\n/g, " ").split(" ");
	let sides = 6;
	let rolls = 1;
	var result = [];
	var output, sum;

	if(input[1] && input[1].startsWith("d")) {
		//Check if it's trying to roll an "n" sided die.
		sides = parseInt(input[1].substring(1).replace(/[^0-9]+/g, ''));
	} else if (input[1]){
		//Roll the dice the number of times stated
		rolls = parseInt(input[1].replace(/[^0-9]+/g, ''));
	}

	if(input[2]) {
		rolls = parseInt(input[1].replace(/[^0-9]+/g, ''));
		sides = parseInt(input[1].replace(/[^0-9]+/g, ''));
	}

	if(!rolls || !sides || rolls < 1 || sides < 2) {
		//You can't roll something with no die, no sides, less than 1 roll or with less than 2 sides.
		MSS.msg.react(message, false, "x");
	}

	if(rolls == 1) {
		output = "Rolled a " + sides + "-sided die.";
	} else {
		//Rolled 6 6-sided dice.
		output = "Rolled " + rolls + " " + sides + "-sided dice.";
	}

	for(i=0; i<rolls; i++) {
		let value = randInt(sides);
		sum += value;
		result.push(value);
	}

	var embed = new Discord.RichEmbed()
		.setTitle("MSS-Discord")
		.setAuthor("roll", "http://moustacheminer.com/mss.png")
		.setColor("#00AE86")
		.setDescription(output)
		.setFooter("MSS-Discord, " + config.MSS.version, "")
		.setTimestamp()
		.setURL("http://moustacheminer.com/")
		.addField("Die output", result)
		.addField("Total", sum);

	message.channel.sendEmbed(embed, "", { disableEveryone: true })
		.catch(function(e) {
			console.log(e);
		});
}

function randInt(d) {
	Math.floor(Math.random() * d) + 1
}
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

define([
    "firebug/firebug",
    "firebug/lib/trace",
    "firebug/js/sourceFile",
    "firebug/js/sourceLink",
    "firebug/chrome/reps",
],
function(Firebug, FBTrace, SourceFile, SourceLink, FirebugReps) {

"use strict"

// ********************************************************************************************* //
// Constants

var Cc = Components.classes;
var Ci = Components.interfaces;

// ********************************************************************************************* //
// ErrorMessageObj Implementation

/**
 * @object This object collects data about an error that happens in the content. It's used
 * by {@ErrorMessage} Domplate template as the data source.
 */
function ErrorMessageObj(message, href, lineNo, source, category, context,
    trace, msgId, colNumber)
{
    this.message = message;
    this.href = href;
    this.lineNo = lineNo;
    this.source = source;
    this.category = category;
    this.context = context;
    this.trace = trace;
    this.msgId = msgId || this.getId();
    this.colNumber = colNumber;
};

ErrorMessageObj.prototype =
/** @lends ErrorMessageObj */
{
    getSourceLine: function()
    {
        if (this.href === null)
            return "";

        if (!this.context.sourceCache)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("reps.ErrorMessageObj.getSourceLine; ERROR no source cache!");
            return "";
        }

        return this.context.sourceCache.getLine(this.href, this.lineNo);
    },

    getSourceLink: function()
    {
        var ext = this.category == "css" ? "css" : "js";
        return this.lineNo ? new SourceLink.SourceLink(this.href, this.lineNo, ext,
            null, null, this.colNumber) : null;
    },

    resetSource: function()
    {
        if (this.href && this.lineNo != null)
            this.source = this.getSourceLine();
    },

    correctWithStackTrace: function(trace)
    {
        var frame = trace.frames[0];
        if (frame)
        {
            this.href = frame.href;
            this.lineNo = frame.line;
            this.trace = trace;
        }
    },

    correctSourcePoint: function(sourceName, lineNumber)
    {
        this.href = sourceName;
        this.lineNo = lineNumber;
    },

    getId: function()
    {
        return this.href + ":" + this.message + ":" + this.lineNo + ":" + this.colNumber;
    }
};

// ********************************************************************************************* //
// Registration

// xxxHonza: back compatibility
FirebugReps.ErrorMessageObj = ErrorMessageObj;

return ErrorMessageObj;

// ********************************************************************************************* //
});
<commit_msg>Just append column number when it's available<commit_after>/* See license.txt for terms of usage */

define([
    "firebug/firebug",
    "firebug/lib/trace",
    "firebug/js/sourceFile",
    "firebug/js/sourceLink",
    "firebug/chrome/reps",
],
function(Firebug, FBTrace, SourceFile, SourceLink, FirebugReps) {

"use strict"

// ********************************************************************************************* //
// Constants

var Cc = Components.classes;
var Ci = Components.interfaces;

// ********************************************************************************************* //
// ErrorMessageObj Implementation

/**
 * @object This object collects data about an error that happens in the content. It's used
 * by {@ErrorMessage} Domplate template as the data source.
 */
function ErrorMessageObj(message, href, lineNo, source, category, context,
    trace, msgId, colNumber)
{
    this.message = message;
    this.href = href;
    this.lineNo = lineNo;
    this.source = source;
    this.category = category;
    this.context = context;
    this.trace = trace;
    this.msgId = msgId || this.getId();
    this.colNumber = colNumber;
};

ErrorMessageObj.prototype =
/** @lends ErrorMessageObj */
{
    getSourceLine: function()
    {
        if (this.href === null)
            return "";

        if (!this.context.sourceCache)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("reps.ErrorMessageObj.getSourceLine; ERROR no source cache!");
            return "";
        }

        return this.context.sourceCache.getLine(this.href, this.lineNo);
    },

    getSourceLink: function()
    {
        var ext = this.category == "css" ? "css" : "js";
        return this.lineNo ? new SourceLink.SourceLink(this.href, this.lineNo, ext,
            null, null, this.colNumber) : null;
    },

    resetSource: function()
    {
        if (this.href && this.lineNo != null)
            this.source = this.getSourceLine();
    },

    correctWithStackTrace: function(trace)
    {
        var frame = trace.frames[0];
        if (frame)
        {
            this.href = frame.href;
            this.lineNo = frame.line;
            this.trace = trace;
        }
    },

    correctSourcePoint: function(sourceName, lineNumber)
    {
        this.href = sourceName;
        this.lineNo = lineNumber;
    },

    getId: function()
    {
        return this.href + ":" + this.message + ":" + this.lineNo + ":" +
            (this.colNumber ? this.colNumber : "");
    }
};

// ********************************************************************************************* //
// Registration

// xxxHonza: back compatibility
FirebugReps.ErrorMessageObj = ErrorMessageObj;

return ErrorMessageObj;

// ********************************************************************************************* //
});
<|endoftext|>


<commit_before>var T = require('../..');
var sleep = T.prankcall.Prankcall.sleep;

describe('Prankcall', function(testDone) {
  'use strict';

  beforeEach(function() {
    var test = this;

    // `this.send` will return one element at a time
    this.expectedCallReturn = [1, 2, 3];

    // To force retries
    this.generatorErrMsg = 'test generator error';
    this.generatorWithError = function *() {
      if (true) { // Hide the `throw` from jshint
        throw new Error(test.generatorErrMsg);
      }
      yield 'make jshint happy';
    };

    this.prankcall = T.prankcall.create();
    this.prankcall.set('sleep', 1);

    // Stand-in for something async like an HTTP request
    this.send = function *() {
      yield sleep(1);
      return test.expectedCallReturn[test.receiveCount];
    };

    // Store values passed to `this.receive`
    this.actualCallReturn = [];

    // Stand-in for something async, ex. write `this.send` results to DB
    this.receive = function *(callReturn) {
      yield sleep(1);
      test.actualCallReturn.push(callReturn);
      return test.receiveCount++ < test.expectedCallReturn.length - 1;
    };

    // To verify devs can omit the final `return` safely (no infinite loop)
    this.receiveWithoutReturn = function *(callReturn) {
      test.actualCallReturn.push(callReturn);
      yield sleep(1);
    };

    // Cursor used to read `this.expectedCallReturn` one element at a time
    this.receiveCount = 0;
  });

  it('should call #send until #receive returns false', function *() {
    this.prankcall.receive(this.receive);
    yield this.prankcall.send(this.send);
    this.actualCallReturn.should.deep.equal(this.expectedCallReturn);
  });

  it('should call #send only once if #receive returns undefined', function *() {
    this.prankcall.receive(this.receiveWithoutReturn);
    yield this.prankcall.send(this.send);
    this.actualCallReturn.should.deep.equal([this.expectedCallReturn[0]]);
  });

  it.skip('should propagate #send exception if retry disabled', function *() {
    yield true;
  });

  it.skip('should recover from sparse #send exceptions', function *() {
    // success + 2 failures + success + failure + success
    // Verify collected call return values
    yield true;
  });

  it.skip('should reset retries after #send success', function *() {
    // Set max failures to 3, failure a total of 4 times in run:
    // - ex. success + 2 failures + success + 2 failures + success
    // Verify collected call return values
    // Use events to collect retry states
    yield true;
  });

  it.skip('should use default retry options', function *() {
    yield true;
  });

  it.skip('should use custom retry options', function *() {
    yield true;
  });

  it.skip('should use default sleep', function *() {
    yield true;
  });

  it.skip('should use custom sleep', function *() {
    yield true;
  });

  it.skip('should emit event: call', function *() {
    // Payload should include
    // - attempt #
    // Emit right before yielding to sender, outside try/catch
    yield true;
  });

  it.skip('should emit event: return', function *() {
    // Payload should include
    // - attempt #
    // - call return?
    yield true;
  });

  it.skip('should emit event: retry', function *() {
    // Payload should include
    // - attempt #
    // - retries used
    // - retries left
    // - error
    yield true;
  });

  it.skip('should emit event: sleep', function *() {
    // Payload should include
    // - attempt #
    // - sleep duration
    yield true;
  });
});

function noOp() { return function(done) { done(); }; }
<commit_msg>test(lib): Verify #send called once by default<commit_after>var T = require('../..');
var sleep = T.prankcall.Prankcall.sleep;

describe('Prankcall', function(testDone) {
  'use strict';

  beforeEach(function() {
    var test = this;

    // `this.send` will return one element at a time
    this.expectedCallReturn = [1, 2, 3];

    // To force retries
    this.generatorErrMsg = 'test generator error';
    this.generatorWithError = function *() {
      if (true) { // Hide the `throw` from jshint
        throw new Error(test.generatorErrMsg);
      }
      yield 'make jshint happy';
    };

    this.prankcall = T.prankcall.create();
    this.prankcall.set('sleep', 1);

    this.sendSpy = this.spy();

    // Stand-in for something async like an HTTP request
    this.send = function *() {
      test.sendSpy();
      yield sleep(1);
      return test.expectedCallReturn[test.receiveCount];
    };

    // Store values passed to `this.receive`
    this.actualCallReturn = [];

    // Stand-in for something async, ex. write `this.send` results to DB
    this.receive = function *(callReturn) {
      yield sleep(1);
      test.actualCallReturn.push(callReturn);
      return test.receiveCount++ < test.expectedCallReturn.length - 1;
    };

    // To verify devs can omit the final `return` safely (no infinite loop)
    this.receiveWithoutReturn = function *(callReturn) {
      test.actualCallReturn.push(callReturn);
      yield sleep(1);
    };

    // Cursor used to read `this.expectedCallReturn` one element at a time
    this.receiveCount = 0;
  });

  it('should call #send until #receive returns false', function *() {
    this.prankcall.receive(this.receive);
    yield this.prankcall.send(this.send);
    this.actualCallReturn.should.deep.equal(this.expectedCallReturn);
  });

  it('should call #send only once if using default #receive', function *() {
    yield this.prankcall.send(this.send);
    this.sendSpy.should.have.been.called.once;
  });

  it('should call #send only once if custom #receive returns undefined', function *() {
    this.prankcall.receive(this.receiveWithoutReturn);
    yield this.prankcall.send(this.send);
    this.actualCallReturn.should.deep.equal([this.expectedCallReturn[0]]);
  });

  it.skip('should propagate #send exception if retry disabled', function *() {
    yield true;
  });

  it.skip('should recover from sparse #send exceptions', function *() {
    // success + 2 failures + success + failure + success
    // Verify collected call return values
    yield true;
  });

  it.skip('should reset retries after #send success', function *() {
    // Set max failures to 3, failure a total of 4 times in run:
    // - ex. success + 2 failures + success + 2 failures + success
    // Verify collected call return values
    // Use events to collect retry states
    yield true;
  });

  it.skip('should use default retry options', function *() {
    yield true;
  });

  it.skip('should use custom retry options', function *() {
    yield true;
  });

  it.skip('should use default sleep', function *() {
    yield true;
  });

  it.skip('should use custom sleep', function *() {
    yield true;
  });

  it.skip('should emit event: call', function *() {
    // Payload should include
    // - attempt #
    // Emit right before yielding to sender, outside try/catch
    yield true;
  });

  it.skip('should emit event: return', function *() {
    // Payload should include
    // - attempt #
    // - call return?
    yield true;
  });

  it.skip('should emit event: retry', function *() {
    // Payload should include
    // - attempt #
    // - retries used
    // - retries left
    // - error
    yield true;
  });

  it.skip('should emit event: sleep', function *() {
    // Payload should include
    // - attempt #
    // - sleep duration
    yield true;
  });
});

function noOp() { return function(done) { done(); }; }
<|endoftext|>


<commit_before>module.exports = (function Nfield () {

  var Promise = require('bluebird');

  var nfieldInstance;

  /**
   * Creates Nfield instance
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   */
  function createNfieldInstance (nfieldParams, requestParams) {

    var request;
    var token = { 'AuthenticationToken' : '', 'Timestamp' : 0 };
    var connectInterval;
    var nfieldOptions = nfieldParams || {};
    var requestOptions = requestParams || {};

    /**
     * Reconfigures Nfield instance
     * @alias configure
     * @param {Object=} nP - Parameters to configure Nfield user to use with API, must contain server url and user credentials
     * @param {Object=} rP - Parameters to configure request module, that is used to connect to API
     */
    function updateParams (nP, rP) {
      nfieldOptions = nP || nfieldOptions;
      requestOptions = rP || requestOptions;
      requestOptions.baseUrl = nfieldOptions.server || 'https://api.nfieldmr.com/';
      request = Promise.promisify(require('request').defaults(requestOptions));
    }

    /**
     * Response callback
     * @callback responseCallback
     * @param {Array} err
     * @param {Array} resp
     */

    /**
     * Sign in to the Nfield API

     * {@link https://api.nfieldmr.com/help/api/post-v1-signin 'POST v1/SignIn' API documentation}
     * @param {Object} credentials - Sign in credentials
     * @param {String} credentials.Domain
     * @param {String} credentials.Username
     * @param {String} credentials.Password
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function signIn (credentials, callback) {
      return request({
        method : 'post',
        uri : 'v1/SignIn',
        json : credentials
      }).nodeify(callback);
    }

    /**
     * Request survey fieldwork status
     * {@link https://api.nfieldmr.com/help/api/get-v1-surveys-surveyid-fieldwork-status 'GET v1/Surveys/{surveyId}/Fieldwork/Status' API documentation}
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function getSurveyStatus (surveyId, callback) {
      return request({
        method : 'get',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Status').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    }

    /**
     * Start survey
     * {@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-start 'PUT v1/Surveys/{surveyId}/Fieldwork/Start' API documentation}
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function startSurvey (surveyId, callback) {
      return request({
        method : 'put',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Start').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    }

    /**
     * Token update error callback
     * @callback persistantErrorCallback
     * @param {Array} error - Request response array
     */

    /**
     * Connects Nfield instance to Nfield API with parameters provided during initialization

     * Nfield API uses tokens that lasts for 15 minutes for authorisation, so as an options this method allows you to initiate an autoupdate for the token in Nfield instance, that fires every 12 minutes
     * @param {Boolean} persistant - Initiate an autoupdate for token (true/false)
     * @param {persistantErrorCallback} persistantErrorCallback - Callback, that fires if something goes wrong during token update
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function connect (persistant, persistantErrorCallback, callback) {
      if (persistant === true && !connectInterval) {
        connectInterval = setInterval(function () {
          signIn(nfieldOptions.credentials).then(function(data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
            } else {
              if (typeof persistantErrorCallback == 'function') persistantErrorCallback(data);
            }
          });
        }, 1000 * 60 * 12);
      } else if (persistant === true && connectInterval) {
        console.log('Persistant connection already running');
      }

      return new Promise(function (resolve, reject) {
        if (token.AuthenticationToken !== '' && (Date.now() - token.Timestamp) < 1000 * 60 * 12) {
          resolve(token);
        } else {
          signIn(nfieldOptions.credentials).then(function (data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
              resolve(token);
            } else {
              reject(data);
            }
          }).catch(function (error) {
            reject(error);
          });
        }
      }).nodeify(callback);
    }

    /**
     * Clears persistant token update interval
     * @alias stop
     */
    function disablePersistant () {
      clearInterval(connectInterval);
      connectInterval = null;
    }

    updateParams(nfieldOptions, requestOptions);

    return {
      configure : updateParams,
      signIn : signIn,
      connect : connect,
      stop : disablePersistant,
      getSurveyStatus : getSurveyStatus,
      startSurvey : startSurvey
    };

  }

  /**
   * Creates new Nfield instance or returns existing one
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {String} nfieldParams.credentials.Domain
   * @param {String} nfieldParams.credentials.Username
   * @param {String} nfieldParams.credentials.Password
   * @param {String} nfieldParams.server
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   * @returns {Object} Returns Nfield instance
   */
  function init (nfieldParams, requestParams) {
    if (!nfieldInstance) {
      nfieldInstance = createNfieldInstance(nfieldParams, requestParams);
    }
    return nfieldInstance;
  }

  return {
    init : init
  };

})();<commit_msg>Add stopSurvey(), add additional commentaries to code<commit_after>module.exports = (function Nfield () {

  var Promise = require('bluebird');

  var nfieldInstance;

  /**
   * Creates Nfield instance
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   */
  function createNfieldInstance (nfieldParams, requestParams) {

    var request;
    var token = { 'AuthenticationToken' : '', 'Timestamp' : 0 };
    var connectInterval;
    var nfieldOptions = nfieldParams || {};
    var requestOptions = requestParams || {};

    /**
     * Reconfigures Nfield instance
     * @alias configure
     * @param {Object=} nP - Parameters to configure Nfield user to use with API, must contain server url and user credentials
     * @param {Object=} rP - Parameters to configure request module, that is used to connect to API
     */
    function updateParams (nP, rP) {
      nfieldOptions = nP || nfieldOptions;
      requestOptions = rP || requestOptions;
      requestOptions.baseUrl = nfieldOptions.server || 'https://api.nfieldmr.com/';
      request = Promise.promisify(require('request').defaults(requestOptions));
    }

    /**
     * Response callback
     * @callback responseCallback
     * @param {Array} err
     * @param {Array} resp
     */

    // SignIn

    /**
     * Sign in to the Nfield API

     * {@link https://api.nfieldmr.com/help/api/post-v1-signin 'POST v1/SignIn' API documentation}
     * @param {Object} credentials - Sign in credentials
     * @param {String} credentials.Domain
     * @param {String} credentials.Username
     * @param {String} credentials.Password
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function signIn (credentials, callback) {
      return request({
        method : 'post',
        uri : 'v1/SignIn',
        json : credentials
      }).nodeify(callback);
    }

    // SurveyFieldwork

    /**
     * Request survey fieldwork status
     * {@link https://api.nfieldmr.com/help/api/get-v1-surveys-surveyid-fieldwork-status 'GET v1/Surveys/{surveyId}/Fieldwork/Status' API documentation}
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function getSurveyStatus (surveyId, callback) {
      return request({
        method : 'get',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Status').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    }

    /**
     * Start survey
     * {@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-start 'PUT v1/Surveys/{surveyId}/Fieldwork/Start' API documentation}
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function startSurvey (surveyId, callback) {
      return request({
        method : 'put',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Start').replace('{surveyId}', surveyId),
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    }

    /**
     * Stop (pause) survey
     * {@link https://api.nfieldmr.com/help/api/put-v1-surveys-surveyid-fieldwork-stop 'PUT v1/Surveys/{surveyId}/Fieldwork/Stop' API documentation}
     * @param {String} surveyId - Survey ID
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function stopSurvey (surveyId, callback) {
      return request({
        method : 'put',
        uri : ('v1/Surveys/{surveyId}/Fieldwork/Stop').replace('{surveyId}', surveyId),
        json : {
          // TODO: Wainig for the answer from the NIPO support to clarify meaning of the variable, value is fixed for now
          'TerminateRunningInterviews' : true
        },
        headers : {
          'Authorization': 'Basic ' + token.AuthenticationToken
  			}
      }).nodeify(callback);
    }

    /**
     * Token update error callback
     * @callback persistantErrorCallback
     * @param {Array} error - Request response array
     */

    /**
     * Connects Nfield instance to Nfield API with parameters provided during initialization

     * Nfield API uses tokens that lasts for 15 minutes for authorisation, so as an options this method allows you to initiate an autoupdate for the token in Nfield instance, that fires every 12 minutes
     * @param {Boolean} persistant - Initiate an autoupdate for token (true/false)
     * @param {persistantErrorCallback} persistantErrorCallback - Callback, that fires if something goes wrong during token update
     * @param {responseCallback=} callback - Optional node-style callback
     * @returns {Promise} Returns a promise of the request
     */
    function connect (persistant, persistantErrorCallback, callback) {
      if (persistant === true && !connectInterval) {
        connectInterval = setInterval(function () {
          signIn(nfieldOptions.credentials).then(function(data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
            } else {
              if (typeof persistantErrorCallback == 'function') persistantErrorCallback(data);
            }
          });
        }, 1000 * 60 * 12);
      } else if (persistant === true && connectInterval) {
        console.log('Persistant connection already running');
      }

      return new Promise(function (resolve, reject) {
        if (token.AuthenticationToken !== '' && (Date.now() - token.Timestamp) < 1000 * 60 * 12) {
          resolve(token);
        } else {
          signIn(nfieldOptions.credentials).then(function (data) {
            if (data[0].statusCode == 200) {
              token.AuthenticationToken = data[0].body.AuthenticationToken;
              token.Timestamp = Date.now();
              resolve(token);
            } else {
              reject(data);
            }
          }).catch(function (error) {
            reject(error);
          });
        }
      }).nodeify(callback);
    }

    /**
     * Clears persistant token update interval
     * @alias stop
     */
    function disablePersistant () {
      clearInterval(connectInterval);
      connectInterval = null;
    }

    updateParams(nfieldOptions, requestOptions);

    return {
      configure : updateParams,
      signIn : signIn,
      connect : connect,
      stop : disablePersistant,
      getSurveyStatus : getSurveyStatus,
      startSurvey : startSurvey,
      stopSurvey : stopSurvey
    };

  }

  /**
   * Creates new Nfield instance or returns existing one
   * @param {Object} nfieldParams - Parameters to configure Nfield user to use with API, must contain server url and user credentials
   * @param {String} nfieldParams.credentials.Domain
   * @param {String} nfieldParams.credentials.Username
   * @param {String} nfieldParams.credentials.Password
   * @param {String} nfieldParams.server
   * @param {Object=} requestParams - Parameters to configure request module, that is used to connect to API
   * @returns {Object} Returns Nfield instance
   */
  function init (nfieldParams, requestParams) {
    if (!nfieldInstance) {
      nfieldInstance = createNfieldInstance(nfieldParams, requestParams);
    }
    return nfieldInstance;
  }

  return {
    init : init
  };

})();<|endoftext|>


<commit_before>'use strict';

var md4mefi = require('../lib/md4mefi');

function doTestCases(test, testCases) {
	testCases.forEach(function(testCase) {
		var mdText = testCase[0];
		var htmlText = testCase[1];

		test.equal(md4mefi.md2html(mdText), htmlText);
	});
}

exports['strip p tags'] = function(test) {
	var testCases = [
		// Don't surround plain text (no newlines) in
 tags.
		[
			'Twenty bucks, same as in town.',
			'Twenty bucks, same as in town.'
		],

		// Single newlines are retained.
		// MeFi will convert them into
 tags.
		[
			"Hi.\nI'm Lenny.\nThis is Carl and Homer.",
			"Hi.\nI'm Lenny.\nThis is Carl and Homer."
		],

		// Double newlines are retained.
		// MeFi will convert them into

		[
			"I like cheese.\n\nI do not like ice cream.",
			"I like cheese.\n\nI do not like ice cream."
		],

		// Test complex paras w/ embedded tags
		[
			"Hello, *Wilbur*, I'm so happy to **see you**.\n\nHow's the wife?",
			"Hello, Wilbur, I'm so happy to see you.\n\nHow's the wife?"
		]
	];
	doTestCases(test, testCases);

	test.done();
};

exports['blockquote'] = function(test) {
	var testCases = [
		// Simple blockquote
		[
			'> Hello',
			'
Hello
'
		],
		// Ensure that two blockquotes produce one HTML blockquote tag
		[
			"> Hello\n\n> I like cheese.",
			"
Hello\n\nI like cheese.
"
		],
		// 3 blockquotes!
		[
			"> Hello\n\n>I like cheese.\n\n>I do not like ice cream.",
			"
Hello\n\nI like cheese.\n\nI do not like ice cream.
"
		],
	];

	doTestCases(test, testCases);
	test.done();
};
<commit_msg>Added tests for lists<commit_after>'use strict';

var md4mefi = require('../lib/md4mefi');

function doTestCases(test, testCases) {
	testCases.forEach(function(testCase) {
		var mdText = testCase[0];
		var htmlText = testCase[1];

		test.equal(md4mefi.md2html(mdText), htmlText);
	});
}

exports['strip p tags'] = function(test) {
	var testCases = [
		// Don't surround plain text (no newlines) in
 tags.
		[
			'Twenty bucks, same as in town.',
			'Twenty bucks, same as in town.'
		],

		// Single newlines are retained.
		// MeFi will convert them into
 tags.
		[
			"Hi.\nI'm Lenny.\nThis is Carl and Homer.",
			"Hi.\nI'm Lenny.\nThis is Carl and Homer."
		],

		// Double newlines are retained.
		// MeFi will convert them into

		[
			"I like cheese.\n\nI do not like ice cream.",
			"I like cheese.\n\nI do not like ice cream."
		],

		// Test complex paras w/ embedded tags
		[
			"Hello, *Wilbur*, I'm so happy to **see you**.\n\nHow's the wife?",
			"Hello, Wilbur, I'm so happy to see you.\n\nHow's the wife?"
		]
	];
	doTestCases(test, testCases);

	test.done();
};

exports['blockquote'] = function(test) {
	var testCases = [
		// Simple blockquote
		[
			'> Hello',
			'
Hello
'
		],
		// Ensure that two blockquotes produce one HTML blockquote tag
		[
			"> Hello\n\n> I like cheese.",
			"
Hello\n\nI like cheese.
"
		],
		// 3 blockquotes!
		[
			"> Hello\n\n>I like cheese.\n\n>I do not like ice cream.",
			"
Hello\n\nI like cheese.\n\nI do not like ice cream.
"
		],
	];

	doTestCases(test, testCases);
	test.done();
};

exports['bullet list'] = function(test) {
	var testCases = [
		[
			'* One',
			'

One

'
		],
		[
			'* One\n* Two',
			'

One

Two

'
		]
	];

	doTestCases(test, testCases);
	test.done();
};

exports['number list'] = function(test) {
	var testCases = [
		[
			'1. One',
			'

One

'
		],
		[
			'1. One\n1. Two',
			'

One

Two

'
		]
	];

	doTestCases(test, testCases);
	test.done();
};
<|endoftext|>