<commit_before>var async = require('async');
var passport = require('passport');
var utils = require('prana').utils;

var rest = module.exports;

/**
 * The route() hook.
 */
rest.route = function(routes, callback) {
  var application = this.application;
  var newRoutes = {};

  var validationResponseCallback = function(callback) {
    return function(error, item, errors) {
      if (error) {
        // Application error.
        return callback(error);
      }
      if (errors && errors.length > 0) {
        // Validation errors.
        return callback(null, errors, 400);
      }
      // Validation passed.
      callback(null, item);
    };
  };

  var basicAuth = function(request, response, callback) {
    passport.authenticate('basic', function(error, account) {
      if (error) {
        return callback(error);
      }

      if (!account) {
        return callback(null, ['Invalid username or password.'], 401);
      }

      // Log user in.
      request.login(account, function(error) {
        if (error) {
          return callback(error);
        }
        callback(null, account);
      });

    })(request, response, callback);
  };

  var self = this;
  async.each(Object.keys(this.application.types), function(typeName, next) {
    var typeModel = self.application.types[typeName];
    var type = typeModel.type;

    // Default path to type name.
    if (!type.path) {
      type.path = '/' + type.name;
    }

    // Initialize access rules.
    type.settings.access = type.settings.access || {};

    // Add default access rules.
    var access = {
      'list': false,
      'load': false,
      'add': false,
      'edit': false,
      'delete': false
    };
    utils.extend(access, type.settings.access);

    // List or add items.
    newRoutes['/rest' + type.path] = {
      callback: function(request, response, callback) {
        if (request.method == 'GET') {
          // @todo: filter out dangerous stuff from query before passing it to
          // list() method?
          var query = request.query;
          return application.invoke('query', type, query, request, function() {
            typeModel.list(query, callback);
          });
        }
        if (request.method == 'POST') {
          return typeModel.validateAndSave(request.body, validationResponseCallback(callback));
        }
        callback();
      },
      access: function(request, response, callback) {
        basicAuth(request, response, function(error, account) {
          if (!account) {
            return callback(null, false);
          }

          if (request.method == 'GET') {
            return application.access(request, access.list, callback);
          }
          if (request.method == 'POST') {
            return application.access(request, access.add, callback);
          }
          callback();
        });
      }
    };

    // Get, update or delete an item.
    newRoutes['/rest' + type.path + '/:' + type.name] = {
      callback: function(request, response, callback) {
        if (request.method == 'GET') {
          return typeModel.load(request.params[type.name], callback);
        }
        if (request.method == 'PUT') {
          return typeModel.validateAndSave(request.body, validationResponseCallback(callback));
        }
        if (request.method == 'POST' || request.method == 'PATCH') {
          return typeModel.load(request.params[type.name], function(err, item) {
            if (item) {
              // Delete MongoDB ID if any.
              delete item._id;
              utils.extend(item, request.body);
              request.body = item;
            }
            typeModel.validateAndSave(request.body, validationResponseCallback(callback));
          });
        }
        if (request.method == 'DELETE') {
          return typeModel.delete(request.params[type.name], callback);
        }
        callback();
      },
      access: function(request, response, callback) {
        basicAuth(request, response, function(error, account) {
          if (!account) {
            return callback(null, false);
          }

          if (request.method == 'GET') {
            return application.access(request, access.load, callback);
          }
          if (request.method == 'PUT' || request.method == 'POST' || request.method == 'PATCH') {
            return application.access(request, access.edit, callback);
          }
          if (request.method == 'DELETE') {
            return application.access(request, access.delete, callback);
          }
          callback();
        });
      }
    };
    next();
  }, function(err) {
    callback(null, newRoutes);
  });
};
<commit_msg>Refactoring REST access callbacks and implementing HTTP Basic auth (#142).<commit_after>var async = require('async');
var passport = require('passport');
var utils = require('prana').utils;

var rest = module.exports;

/**
 * The route() hook.
 */
rest.route = function(routes, callback) {
  var application = this.application;
  var newRoutes = {};

  var validationResponseCallback = function(callback) {
    return function(error, item, errors) {
      if (error) {
        // Application error.
        return callback(error);
      }
      if (errors && errors.length > 0) {
        // Validation errors.
        return callback(null, errors, 400);
      }
      // Validation passed.
      callback(null, item);
    };
  };

  // Helper function for performing HTTP Basic authentication.
  var basicAuth = function(request, response, callback) {
    passport.authenticate('basic', function(error, account) {
      if (error) {
        return callback(error);
      }

      if (!account) {
        return callback(null, ['Invalid username or password.'], 401);
      }

      // Log user in.
      request.login(account, function(error) {
        if (error) {
          return callback(error);
        }
        callback(null, account);
      });

    })(request, response, callback);
  };

  var self = this;
  async.each(Object.keys(this.application.types), function(typeName, next) {
    var typeModel = self.application.types[typeName];
    var type = typeModel.type;

    // Default path to type name.
    if (!type.path) {
      type.path = '/' + type.name;
    }

    // Initialize access rules.
    type.settings.access = type.settings.access || {};

    // Add default access rules.
    var access = {
      'list': false,
      'load': false,
      'add': false,
      'edit': false,
      'delete': false
    };
    utils.extend(access, type.settings.access);

    // Helper function that receives a HTTP method/Model method mapper and run
    // the appropriate access checks.
    var accessHelper = function(methodMapper, request, response, callback) {
      var modelMethod = methodMapper[request.method];
      if (access[modelMethod] === true) {
        return callback(null, true);
      }

      // Run basic auth authentication.
      basicAuth(request, response, function(error, account) {
        if (!account) {
          return callback(null, false);
        }
        if (request.method in methodMapper) {
          return application.access(request, access[modelMethod], callback);
        }
        callback();
      });
    };

    // List or add items.
    newRoutes['/rest' + type.path] = {
      callback: function(request, response, callback) {
        if (request.method == 'GET') {
          // @todo: filter out dangerous stuff from query before passing it to
          // list() method?
          var query = request.query;
          return application.invoke('query', type, query, request, function() {
            typeModel.list(query, callback);
          });
        }
        if (request.method == 'POST') {
          return typeModel.validateAndSave(request.body, validationResponseCallback(callback));
        }
        callback();
      },
      access: function(request, response, callback) {
        var methodMapper = {
          'GET': 'list',
          'POST': 'add'
        };
        accessHelper(methodMapper, request, response, callback);
      }
    };

    // Get, update or delete an item.
    newRoutes['/rest' + type.path + '/:' + type.name] = {
      callback: function(request, response, callback) {
        if (request.method == 'GET') {
          return typeModel.load(request.params[type.name], callback);
        }
        if (request.method == 'PUT') {
          return typeModel.validateAndSave(request.body, validationResponseCallback(callback));
        }
        if (request.method == 'POST' || request.method == 'PATCH') {
          return typeModel.load(request.params[type.name], function(err, item) {
            if (item) {
              // Delete MongoDB ID if any.
              delete item._id;
              utils.extend(item, request.body);
              request.body = item;
            }
            typeModel.validateAndSave(request.body, validationResponseCallback(callback));
          });
        }
        if (request.method == 'DELETE') {
          return typeModel.delete(request.params[type.name], callback);
        }
        callback();
      },
      access: function(request, response, callback) {
        var methodMapper = {
          'GET': 'load',
          'PUT': 'edit',
          'POST': 'edit',
          'PATCH': 'edit',
          'PUT': 'delete'
        };
        accessHelper(methodMapper, request, response, callback);
      }
    };
    next();
  }, function(err) {
    callback(null, newRoutes);
  });
};
<|endoftext|>


<commit_before>/**
 * Compatibility shims for legacy JavaScript engines
 */

// http://soledadpenades.com/2007/05/17/arrayindexof-in-internet-explorer/
if(!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(obj){
    for(var i = 0; i < this.length; i++){
      if(this[i] == obj){
        return i;
      }
    }
    return -1;
  };
}

// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i < len; ++i) {
      fn.call(scope || this, this[i], i, this);
    }
  }
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if(!Array.isArray) {
  Array.isArray = function (vArg) {
    return Object.prototype.toString.call(vArg) === "[object Array]";
  };
}

// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.com/#x15.4.4.19
if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {

    var T, A, k;

    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }

    // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== "function") {
      throw new TypeError(callback + " is not a function");
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if (thisArg) {
      T = thisArg;
    }

    // 6. Let A be a new array created as if by the expression new Array(len) where Array is
    // the standard built-in constructor with that name and len is the value of len.
    A = new Array(len);

    // 7. Let k be 0
    k = 0;

    // 8. Repeat, while k < len
    while(k < len) {

      var kValue, mappedValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
        kValue = O[ k ];

        // ii. Let mappedValue be the result of calling the Call internal method of callback
        // with T as the this value and argument list containing kValue, k, and O.
        mappedValue = callback.call(T, kValue, k, O);

        // iii. Call the DefineOwnProperty internal method of A with arguments
        // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true},
        // and false.

        // In browsers that support Object.defineProperty, use the following:
        // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });

        // For best browser support, use the following:
        A[ k ] = mappedValue;
      }
      // d. Increase k by 1.
      k++;
    }

    // 9. return A
    return A;
  };
}

// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/every
if (!Array.prototype.every) {
  Array.prototype.every = function(fun /*, thisp */) {
    "use strict";

    if (this == null) {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun != "function") {
      throw new TypeError();
    }

    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in t && !fun.call(thisp, t[i], i, t)) {
        return false;
      }
    }

    return true;
  };
}

// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some
if (!Array.prototype.some) {
  Array.prototype.some = function(fun /*, thisp */) {
    "use strict";

    if (this == null) {
      throw new TypeError();
    }

    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun != "function") {
      throw new TypeError();
    }

    var thisp = arguments[1];
    for (var i = 0; i < len; i++) {
      if (i in t && fun.call(thisp, t[i], i, t)) {
        return true;
      }
    }

    return false;
  };
}

// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
              ? this
              : oThis,
              aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}
<commit_msg>Removed unused shim.js<commit_after><|endoftext|>


<commit_before>var mbaasApi = require('fh-mbaas-api');

var globalRequestInterceptor = function(dataset_id, params, cb) {
  // This function will intercept all sync requests.
  // It is useful for checking client identities and
  // for validating authentication

  console.log('lib/sync.js - Intercepting request for dataset', dataset_id, 'with params', params);

  // Return a non null response to cause the sync request to fail.
  // This (string) response will be returned to the client, so
  // don't leak any security information.
  return cb(null);
}

mbaasApi.sync.globalInterceptRequest(globalRequestInterceptor);<commit_msg>update file /lib/sync.js<commit_after>var mbaasApi = require('fh-mbaas-api');

var globalRequestInterceptor = function(dataset_id, params, cb) {
  // This function will intercept all sync requests.
  // It is useful for checking client identities and
  // for validating authentication

  console.log('lib/sync.js - For session', mbaasApi.session.get(params.sessionToken[0]));

  // Return a non null response to cause the sync request to fail.
  // This (string) response will be returned to the client, so
  // don't leak any security information.
  return cb(null);
}

mbaasApi.sync.globalInterceptRequest(globalRequestInterceptor);<|endoftext|>


<commit_before>
var internals = {};
internals.DEFAULT_STATUS = 'active';

internals.data = require('./models');

//This function checks that the input id is of the right type. it does not check if the id exists for an item in the database.
exports.isValidID = internals.isValidID = function isValidID(input) {
	var isValid = true;
	var original = input;

	input = parseInt(input);

	var isBad = isNaN(input) || original !== input;

	isValid = !isBad;

	return isValid;
}

var Task = {};

Task.add = function(input, callback) {
	var errorMessages = [];
	//validate fields
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}
	if (!input.name) {
		errorMessages.push('Object field "name" is required.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		var task_status = internals.DEFAULT_STATUS; //default
		if (input.status) {
			task_status = input.status;
		}
		internals.data.User.find(parseInt(input.user)).success(function(user) {
			if (user == null) {
				//bad input, associated user doesn't exist, handle
				errorMessages.push('The user does not exist.');
				callback(new Error(errorMessages));
			} else {
				internals.data.Task.create({ name: input.name, status: task_status }).success(function(newTask) {
					newTask.setUser(user).success(function() {
						//success
						callback(null, newTask);
					});
				});
			}
		})
	}
}

Task.activate = function(input, callback) {
	var errorMessages = [];
	//test existence of fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			//console.log(task.user);// .email
			var output = {};

			output.id = task.id;
			output.name = task.name;
			output.userid = task.user.id;
			output.email = task.user.email;
			output.createdAt = task.createdAt;
			output.updatedAt = task.updatedAt;
			output.status = 'active';
			callback(null, output);
		});
	}
}

Task.inactivate = function(input, callback) {
	var errorMessages = [];
	//test existence of fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			//console.log(task.user);// .email
			var output = {};

			output.id = task.id;
			output.name = task.name;
			output.userid = task.user.id;
			output.email = task.user.email;
			output.createdAt = task.createdAt;
			output.updatedAt = task.updatedAt;
			output.status = 'inactive';
			callback(null, output);
		});
	}
}

Task.delete = function(input, callback) {
	var errorMessages = [];
	//test existence of fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "taskid" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			//console.log(task.user);// .email
			var output = {};

			output.id = task.id;
			output.name = task.name;
			output.userid = task.user.id;
			output.email = task.user.email;
			output.createdAt = task.createdAt;
			output.updatedAt = task.updatedAt;
			output.status = 'deleted';
			callback(null, output);
		});
	}
}

Task.update = function(input, callback) {
	var errorMessages = [];
	//test existence of required fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//TODO optional fields
	//name , status

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		callback(new Error('Not yet implemented.'));
	}
}

Task.get = function(input, callback) {
	var errorMessages = [];
	//test existence of required fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//TODO: test if input is an array in case they pass an array of ids.
	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		callback(new Error('Not yet implemented.'));
	}
}

Task.getAll = function(input, callback) {
	var errorMessages = [];
	//test existence of required fields
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}
	//TODO: optional fields:
	// order, group, where, limit, offset
	//TODO: test if input is an array in case they pass an array of ids.
	//validate fields

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		callback(new Error('Not yet implemented.'));
	}
}

module.exports = Task;
<commit_msg>Fixed some bad code and added Faire.Task.update()<commit_after>
var internals = {};
internals.DEFAULT_STATUS = 'active';

internals.data = require('./models');

//This function checks that the input id is of the right type. it does not check if the id exists for an item in the database.
exports.isValidID = internals.isValidID = function isValidID(input) {
	var isValid = true;
	var original = input;

	input = parseInt(input);

	var isBad = isNaN(input) || original !== input;

	isValid = !isBad;

	return isValid;
}

var Task = {};

Task.add = function(input, callback) {
	var errorMessages = [];
	//validate fields
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}
	if (!input.name) {
		errorMessages.push('Object field "name" is required.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		var task_status = internals.DEFAULT_STATUS; //default
		if (input.status) {
			task_status = input.status;
		}
		internals.data.User.find(parseInt(input.user)).success(function(user) {
			if (user == null) {
				//bad input, associated user doesn't exist, handle
				errorMessages.push('The user does not exist.');
				callback(new Error(errorMessages));
			} else {
				internals.data.Task.create({ name: input.name, status: task_status }).success(function(newTask) {
					newTask.setUser(user).success(function() {
						//success
						callback(null, newTask);
					});
				});
			}
		})
	}
}

Task.activate = function(input, callback) {
	var errorMessages = [];
	//test existence of fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			task.updateAttributes({
				status: 'active'
			}).success(function(output_task) {
				var output = {};

				output.id = output_task.id;
				output.name = output_task.name;
				output.userid = output_task.user.id;
				output.email = output_task.user.email;
				output.createdAt = output_task.createdAt;
				output.updatedAt = output_task.updatedAt;
				output.status = output_task.status;
				callback(null, output);
			})
		});
	}
}

Task.inactivate = function(input, callback) {
	var errorMessages = [];
	//test existence of fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			task.updateAttributes({
				status: 'inactive'
			}).success(function(output_task) {
				var output = {};

				output.id = output_task.id;
				output.name = output_task.name;
				output.userid = output_task.user.id;
				output.email = output_task.user.email;
				output.createdAt = output_task.createdAt;
				output.updatedAt = output_task.updatedAt;
				output.status = output_task.status;
				callback(null, output);
			})
		});
	}
}

Task.delete = function(input, callback) {
	var errorMessages = [];
	//test existence of fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "taskid" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			task.updateAttributes({
				status: 'deleted'
			}).success(function(output_task) {
				var output = {};

				output.id = output_task.id;
				output.name = output_task.name;
				output.userid = output_task.user.id;
				output.email = output_task.user.email;
				output.createdAt = output_task.createdAt;
				output.updatedAt = output_task.updatedAt;
				output.status = output_task.status;
				callback(null, output);
			})
		});
	}
}

Task.update = function(input, callback) {
	var errorMessages = [];
	//test existence of required fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	//optional fields
	//name , status
	var updateThese = {};
	if (input.name) {
		updateThese.name = input.name;
	}
	if (input.status) {
		updateThese.status = input.status;
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		internals.data.Task.find({ where: { id: input.id, UserId: input.user }, include: [internals.data.User] }).success(function(task) {
			task.updateAttributes(updateThese).success(function(output_task) {
				var output = {};

				output.id = output_task.id;
				output.name = output_task.name;
				output.userid = output_task.user.id;
				output.email = output_task.user.email;
				output.createdAt = output_task.createdAt;
				output.updatedAt = output_task.updatedAt;
				output.status = output_task.status;
				callback(null, output);
			})
		});
	}
}

Task.get = function(input, callback) {
	var errorMessages = [];
	//test existence of required fields
	if (!input.id) {
		errorMessages.push('Object field "id" is required.');
	}
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}

	//TODO: test if input is an array in case they pass an array of ids.
	//validate fields
	if (!internals.isValidID(input.id)) {
		errorMessages.push('Object field "id" must be an integer.');
	}

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		callback(new Error('Not yet implemented.'));
	}
}

Task.getAll = function(input, callback) {
	var errorMessages = [];
	//test existence of required fields
	if (!input.user) {
		errorMessages.push('Object field "user" is required.');
	}
	//TODO: optional fields:
	// order, group, where, limit, offset
	//TODO: test if input is an array in case they pass an array of ids.
	//validate fields

	if (errorMessages.length > 0) {
		callback(new Error(errorMessages));
	} else {
		//TODO
		callback(new Error('Not yet implemented.'));
	}
}

module.exports = Task;
<|endoftext|>


<commit_before>/**
 * task.js
 *
 * Copyright (C) 2013 by Florian Holzapfel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
**/
var utils = require('./utils');

var task = function(client, xml) {
	this.client = client;
	if(xml) {
		utils.parse_xml(this, xml.task || xml);
	}
};
task.prototype.delete = function(callback) {
	var url = '/tasks/' + this.id + '.xml';

	this.client.send('DELETE', url, function(err, res) {
		callback(err);
	});
};
task.prototype.get = function(id, callback) {
	this.client.get_item('/tasks/' + id + '.xml', callback, task);
};

module.exports = task;
<commit_msg>ADD: create update complete tasks<commit_after>/**
 * task.js
 *
 * Copyright (C) 2013 by Florian Holzapfel
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
**/
var utils = require('./utils');
var util = require('util');

var task = function(client, xml) {
	this.client = client;
	if(xml) {
		utils.parse_xml(this, xml.task || xml);
	}
};
task.prototype.create = function(item, callback) {
	this.client.create_item('/tasks.xml', utils.to_xml(item, 'task'), callback, company);
};
task.prototype.complete = function(done_at, callback) {
	if(typeof done_at === "function") {
		callback = done_at;
		done_at = new Date();
	}

	var path = '/tasks/' + this.id + '/complete.xml';
	var xml = util.format('<task><done-at>%s</done-at></task>', done_at.toISOString())
	this.client.send('PUT', path, this.to_xml(), callback);
};
task.prototype.delete = function(callback) {
	var url = '/tasks/' + this.id + '.xml';

	this.client.send('DELETE', url, function(err, res) {
		callback(err);
	});
};
task.prototype.get = function(id, callback) {
	this.client.get_item('/tasks/' + id + '.xml', callback, task);
};
task.prototype.to_xml = function(excluded_keys) {
	return utils.to_xml(this, 'task', excluded_keys);
};
task.prototype.update = function(callback) {
	var path = '/tasks/' + this.id + '.xml';
	this.client.send('PUT', path, this.to_xml(), callback);
};

module.exports = task;
<|endoftext|>


<commit_before>var fs = require("fs");
var resumeSchema = require("resume-schema");
var colors = require("colors");
var chalk = require("chalk"); // slowly replace colors with chalk

var symbols = {
  ok: "\u2713",
  err: "\u2717"
};

// win32 console default output fonts don't support tick/cross
if (process && process.platform === "win32") {
  symbols = {
    ok: "\u221A",
    err: "\u00D7"
  };
}

var tick = chalk.green(symbols.ok);
var cross = chalk.red(symbols.err);

//converts the schema's returned path output, to JS object selection notation.
function pathFormatter(path) {
  var jsonPath = path.split("/");
  jsonPath.shift();
  jsonPath = jsonPath.join(".");
  jsonPath = jsonPath.replace(".[", "[");
  return jsonPath;
}

function errorFormatter(errors) {
  //if json parse errors
  // if (readFileErrors) {
  //     console.log('    ', cross + '  ' + chalk.gray(readFileErrors));
  //     console.log(chalk.red('\n  fail  ' + errors.errors.length), '\n');
  //     console.log('Visit'.cyan, 'http://jsonlint.com/', 'for details on correct .json fromatting.'.cyan);
  //     return;
  // }

  errors.errors.forEach(function(error) {
    console.log(
      "    ",
      cross,
      chalk.gray(
        pathFormatter(error.path),
        "is",
        error.params.type,
        ", expected",
        error.params.expected ? error.params.expected : error.params.format
      )
    );
  });

  console.log(chalk.red("\n  fail  " + errors.errors.length), "\n");
  console.log("Please fix your resume.json file and try again"); //wording? link to docs
}

function validate(resumeData, callback) {
  console.log("\n  running validation tests on resume.json ... \n");
  resumeSchema.validate(resumeData, function(errs, report) {
    if (errs) {
      // or json parse errors
      var temp =
        "Cannot export. There are errors in your resume.json schema format.\n";
      if (resumeData === undefined) {
        temp += "Try using The JSONLint Validator at: https://jsonlint.com/\n";
        errs.errors[0].params.type = "unparsable";
        errs.errors[0].params.expected = "json";
      }
      callback(true, {
        message: temp
      });
      errorFormatter(errs);
      process.exit(1);
    } else {
      console.log("  " + tick + " Passed all validation tests. \n".green);
      // console.log(report)

      callback(false);
    }
  });
}

module.exports = {
  validate: validate,
  errorFormatter: errorFormatter
};

//TODO error handling for single quotes

// use json error handler to pinpoint errors
<commit_msg>Patch for error format issue<commit_after>var fs = require("fs");
var resumeSchema = require("resume-schema");
var colors = require("colors");
var chalk = require("chalk"); // slowly replace colors with chalk

var symbols = {
  ok: "\u2713",
  err: "\u2717"
};

// win32 console default output fonts don't support tick/cross
if (process && process.platform === "win32") {
  symbols = {
    ok: "\u221A",
    err: "\u00D7"
  };
}

var tick = chalk.green(symbols.ok);
var cross = chalk.red(symbols.err);

//converts the schema's returned path output, to JS object selection notation.
function pathFormatter(path) {
  var jsonPath = path.split("/");
  jsonPath.shift();
  jsonPath = jsonPath.join(".");
  jsonPath = jsonPath.replace(".[", "[");
  return jsonPath;
}

function errorFormatter(errors) {
  //if json parse errors
  // if (readFileErrors) {
  //     console.log('    ', cross + '  ' + chalk.gray(readFileErrors));
  //     console.log(chalk.red('\n  fail  ' + errors.errors.length), '\n');
  //     console.log('Visit'.cyan, 'http://jsonlint.com/', 'for details on correct .json fromatting.'.cyan);
  //     return;
  // }

  errors.forEach(function(error) {
    console.log(
      "    ",
      cross,
      chalk.gray(
        pathFormatter(error.path),
        "is",
        error.params.type,
        ", expected",
        error.params.expected ? error.params.expected : error.params.format
      )
    );
  });

  console.log(chalk.red("\n  fail  " + errors.length), "\n");
  console.log("Please fix your resume.json file and try again"); //wording? link to docs
}

function validate(resumeData, callback) {
  console.log("\n  running validation tests on resume.json ... \n");
  resumeSchema.validate(resumeData, function(errs, report) {
    if (errs) {
      // or json parse errors
      var temp =
        "Cannot export. There are errors in your resume.json schema format.\n";
      if (resumeData === undefined) {
        temp += "Try using The JSONLint Validator at: https://jsonlint.com/\n";
        errs.errors[0].params.type = "unparsable";
        errs.errors[0].params.expected = "json";
      }
      callback(true, {
        message: temp
      });
      errorFormatter(errs);
      process.exit(1);
    } else {
      console.log("  " + tick + " Passed all validation tests. \n".green);
      // console.log(report)

      callback(false);
    }
  });
}

module.exports = {
  validate: validate,
  errorFormatter: errorFormatter
};

//TODO error handling for single quotes

// use json error handler to pinpoint errors
<|endoftext|>


<commit_before>'use strict';
var util = require('util');
var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var fnName = require('fn-name');
var claim = require('claim');

/**
 * Initialize a new `Test`
 *
 * @param {String} title
 * @param {Function} fn
 * @api public
 */

function Test(title, fn) {
	if (!(this instanceof Test)) {
		return new Test(title, fn);
	}

	if (typeof title !== 'string') {
		fn = title;
		title = null;
	}

	EventEmitter.call(this);

	this.title = title || fnName(fn) || '[anonymous]';
	this.fn = fn;
	this.assertCount = 0;
	this.planCount = null;
}

util.inherits(Test, EventEmitter);
module.exports = Test;

Test.prototype._assert = function () {
	if (++this.assertCount === this.planCount) {
		setImmediate(this.exit.bind(this));
	}
}

// TODO: find a better way to count assertions
// decorate the `claim` methods with our assert counter
Object.keys(claim).forEach(function (el) {
	Test.prototype[el] = function () {
		this._assert();
		claim[el].apply(claim, arguments);
	};
});

/**
 * Plan number of assertions
 *
 * @param {Number} count
 * @api public
 */

Test.prototype.plan = function (count) {
	if (typeof count !== 'number') {
		throw new TypeError('Expected a number');
	}

	this.planCount = count;
};

/**
 * Skip test
 *
 * @api public
 */

Test.prototype.skip = function () {
	this.skipTest = true;
};

/**
 * Run test
 *
 * @param {Function} cb
 * @api public
 */

Test.prototype.run = function (cb) {
	this.cb = cb;

	if (!this.fn || this.skipTest) {
		this.exit();
	}

	try {
		this.fn(this);
	} catch (err) {
		this.assertError = err;
		this.exit();
	}
};

/**
 * End test
 *
 * @api public
 */

Test.prototype.end = function () {
	if (this.endCalled) {
		throw new Error('.end() called more than once');
	}

	this.endCalled = true;
	this.exit();
};

/**
 * Exit test
 *
 * @api private
 */

Test.prototype.exit = function () {
	if (this.planCount !== null && this.planCount !== this.assertCount) {
		this.assertError = new assert.AssertionError({
			actual: this.assertCount,
			expected: this.planCount,
			message: 'Assertion count does not match planned',
			operator: 'plan'
		});
	}

	if (!this.ended) {
		this.ended = true;

		setImmediate(function () {
			this.cb.call(this, this.assertError);
		}.bind(this));
	}
};
<commit_msg>pass along the fn to the plan!==count assertion<commit_after>'use strict';
var util = require('util');
var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var fnName = require('fn-name');
var claim = require('claim');

/**
 * Initialize a new `Test`
 *
 * @param {String} title
 * @param {Function} fn
 * @api public
 */

function Test(title, fn) {
	if (!(this instanceof Test)) {
		return new Test(title, fn);
	}

	if (typeof title !== 'string') {
		fn = title;
		title = null;
	}

	EventEmitter.call(this);

	this.title = title || fnName(fn) || '[anonymous]';
	this.fn = fn;
	this.assertCount = 0;
	this.planCount = null;
}

util.inherits(Test, EventEmitter);
module.exports = Test;

Test.prototype._assert = function () {
	if (++this.assertCount === this.planCount) {
		setImmediate(this.exit.bind(this));
	}
}

// TODO: find a better way to count assertions
// decorate the `claim` methods with our assert counter
Object.keys(claim).forEach(function (el) {
	Test.prototype[el] = function () {
		this._assert();
		claim[el].apply(claim, arguments);
	};
});

/**
 * Plan number of assertions
 *
 * @param {Number} count
 * @api public
 */

Test.prototype.plan = function (count) {
	if (typeof count !== 'number') {
		throw new TypeError('Expected a number');
	}

	this.planCount = count;
};

/**
 * Skip test
 *
 * @api public
 */

Test.prototype.skip = function () {
	this.skipTest = true;
};

/**
 * Run test
 *
 * @param {Function} cb
 * @api public
 */

Test.prototype.run = function (cb) {
	this.cb = cb;

	if (!this.fn || this.skipTest) {
		this.exit();
	}

	try {
		this.fn(this);
	} catch (err) {
		this.assertError = err;
		this.exit();
	}
};

/**
 * End test
 *
 * @api public
 */

Test.prototype.end = function () {
	if (this.endCalled) {
		throw new Error('.end() called more than once');
	}

	this.endCalled = true;
	this.exit();
};

/**
 * Exit test
 *
 * @api private
 */

Test.prototype.exit = function () {
	if (this.planCount !== null && this.planCount !== this.assertCount) {
		this.assertError = new assert.AssertionError({
			actual: this.assertCount,
			expected: this.planCount,
			message: 'Assertion count does not match planned',
			operator: 'plan',
			stackStartFunction: this.fn // TODO: find out why it doesn't show any stack
		});
	}

	if (!this.ended) {
		this.ended = true;

		setImmediate(function () {
			this.cb.call(this, this.assertError);
		}.bind(this));
	}
};
<|endoftext|>


<commit_before><commit_msg>test removed<commit_after><|endoftext|>


<commit_before>/*
 * This file is part of the MicroPython project, http://micropython.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017, 2018 Rami Ali
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

mergeInto(LibraryManager.library, {
    mp_js_write: function(ptr, len) {
        for (var i = 0; i < len; ++i) {
            c = String.fromCharCode(getValue(ptr + i, 'i8'));
            if (typeof window === 'undefined') {
                process.stdout.write(c);
            } else {
                var mp_js_stdout = document.getElementById('mp_js_stdout');
                var print = new Event('print');
                print.data = c;
                mp_js_stdout.dispatchEvent(print);
            }
        }
    },

    mp_js_ticks_ms: function() {
        return (new Date()).getTime() - MP_JS_EPOCH;
    },

    mp_js_hook: function() {
        if (typeof window === 'undefined') {
            var mp_interrupt_char = Module.ccall('mp_hal_get_interrupt_char', 'number', ['number'], ['null']);
            var fs = require('fs');

            var buf = new Buffer(1);
            try {
                var n = fs.readSync(process.stdin.fd, buf, 0, 1);
                if (n > 0) {
                    if (buf[0] == mp_interrupt_char) {
                        Module.ccall('mp_keyboard_interrupt', 'null', ['null'], ['null']);
                    } else {
                        process.stdout.write(String.fromCharCode(buf[0]));
                    }
                }
            } catch (e) {
                if (e.code === 'EAGAIN') {
                } else {
                    throw e;
                }
            }
        }
    },
});
<commit_msg>javascript/library: Use Buffer.alloc() since new Buffer() is deprecated.<commit_after>/*
 * This file is part of the MicroPython project, http://micropython.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017, 2018 Rami Ali
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

mergeInto(LibraryManager.library, {
    mp_js_write: function(ptr, len) {
        for (var i = 0; i < len; ++i) {
            c = String.fromCharCode(getValue(ptr + i, 'i8'));
            if (typeof window === 'undefined') {
                process.stdout.write(c);
            } else {
                var mp_js_stdout = document.getElementById('mp_js_stdout');
                var print = new Event('print');
                print.data = c;
                mp_js_stdout.dispatchEvent(print);
            }
        }
    },

    mp_js_ticks_ms: function() {
        return (new Date()).getTime() - MP_JS_EPOCH;
    },

    mp_js_hook: function() {
        if (typeof window === 'undefined') {
            var mp_interrupt_char = Module.ccall('mp_hal_get_interrupt_char', 'number', ['number'], ['null']);
            var fs = require('fs');

            var buf = Buffer.alloc(1);
            try {
                var n = fs.readSync(process.stdin.fd, buf, 0, 1);
                if (n > 0) {
                    if (buf[0] == mp_interrupt_char) {
                        Module.ccall('mp_keyboard_interrupt', 'null', ['null'], ['null']);
                    } else {
                        process.stdout.write(String.fromCharCode(buf[0]));
                    }
                }
            } catch (e) {
                if (e.code === 'EAGAIN') {
                } else {
                    throw e;
                }
            }
        }
    },
});
<|endoftext|>


<commit_before>const request = require('supertest')
const { last, isArray, isFunction, forIn } = require('lodash')
const { expect, test, afterAll, beforeEach } = global
const Promise = require('bluebird')
const context = {}

function getPathWithContext (paths, index, items) {
  index = parseInt(index)
  let path = ''
  for (var i = 0; i <= index; i++) {
    if (i === index) {
      path += `${paths[index]}`
    } else {
      path += `${paths[i]}/${items[i].id}`
    }
  }
  return path
}

function assertSuccess (status, attrs = null) {
  return (res, strict = true) => {
    expect(res.status).toBe(status)
    if (attrs && strict) {
      forIn(attrs, (v, k) => {
        expect(res.body[k]).toEqual(v)
      })
    }
  }
}

function assertError () {
  return e => { throw e }
}

class ResourceTester {
  constructor (server, paths, options) {
    options = Object.assign({
      teardown: true
    }, options)
    this.server = server
    this.middlewares = []
    this.paths = !isArray(paths) ? [paths] : paths
    if (options.teardown) {
      afterAll(async () => {
        await Promise.promisify(this.server.close).call(this.server)
      })
    }
  }
  get testPath () { return this.paths.join('/:id') }
  use (...middlewares) {
    this.middlewares = this.middlewares.concat(middlewares)
    return this
  }
  async setup (setup) {
    beforeEach(async () => {
      const utils = {
        request: async (nestedDatas, options = {}) => {
          const { use = req => req } = options
          const middleares = [ use ]
          const items = []
          const responses = []
          for (const index in nestedDatas) {
            const data = nestedDatas[index]
            const response = middleares.reduce(
              (req, middleware) => {
                middleware(req)
                return req
              },
              request(this.server).post(getPathWithContext(this.paths, index, items))
            ).send(data)
            items.push((await response).body)
            responses.push(response)
          }
          return { items, responses }
        }
      }
      setup = isFunction(setup) ? setup : async ({request}) => {
        return await request(!isArray(setup) ? [setup] : setup)
      }
      Object.assign(context, await setup(utils))
    })

    return this
  }
  create (data = null, options = {}) {
    const { assert = assertSuccess(201, data), assertCatch = assertError(), use = req => req } = options
    test(`POST ${this.testPath}`, async () => {
      const response = !data
        ? last(context.responses)
        : this.applyMiddleware(use, request(this.server).post(
          getPathWithContext(this.paths, this.paths.length - 1, context.items)
        )).send(data)
      await response.then(res => {
        assert(res, { success: assertSuccess(201, data) })
      }).catch(assertCatch)
    })
    return this
  }
  applyMiddleware (middleware, req) {
    const middlewares = [ middleware ].concat(this.middlewares)
    return middlewares.reduce((req, middleware) => {
      middleware(req)
      return req
    }, req)
  }
  read (data = null, options = {}) {
    this.list(data, options)
    this.item(data, options)
    return this
  }
  list (data = null, options = {}) {
    const { assert = assertSuccess(200), assertCatch = assertError(), use = req => req } = options
    test(`LIST ${this.testPath}`, async () => {
      if (data) {
        const req = request(this.server).post(
          getPathWithContext(this.paths, this.paths.length - 1, context.items)
        )
        if (isFunction(data)) {
          await data({req})
        } else {
          await req.send(data)
        }
      }
      const response = this.applyMiddleware(use, request(this.server).get(
        getPathWithContext(this.paths, this.paths.length - 1, context.items)
      ))
      await response.then(res => {
        assert(res, { success: assertSuccess(200) })
      }).catch(assertCatch)
    })
    return this
  }
  item (data = null, options = {}) {
    const { assert = assertSuccess(200), assertCatch = assertError(), use = req => req } = options
    test(`GET ${this.testPath}/:id`, async () => {
      let item
      if (data) {
        const req = request(this.server).post(
          getPathWithContext(this.paths, this.paths.length - 1, context.items)
        )
        let res
        if (isFunction(data)) {
          res = await data({req})
        } else {
          res = await req.send(data)
        }
        item = res.body
      } else {
        item = last(context.items)
      }
      const response = this.applyMiddleware(use, request(this.server).get(
        `${getPathWithContext(this.paths, this.paths.length - 1, context.items)}/${item.id}`
      ))
      await response.then(res => {
        assert(res, { success: assertSuccess(200), item })
      }).catch(assertCatch)
    })
    return this
  }
  update (data = null, options = {}) {
    const { assert = assertSuccess(202), assertCatch = assertError(), use = req => req, patch } = options
    test(`PATCH ${this.testPath}/:id`, async () => {
      let item
      if (data) {
        const req = request(this.server).post(
          getPathWithContext(this.paths, this.paths.length - 1, context.items)
        )
        let res
        if (isFunction(data)) {
          res = await data({req})
        } else {
          res = await req.send(data)
        }
        item = res.body
      } else {
        item = last(context.items)
      }

      const response = this.applyMiddleware(use, request(this.server).patch(
        `${getPathWithContext(this.paths, this.paths.length - 1, context.items)}/${item.id}`
      )).send(patch)
      await response.then(res => {
        assert(res, { success: assertSuccess(202, patch) })
      }).catch(assertCatch)
    })
    return this
  }
  destroy (data = null, options = {}) {
    const { assert = assertSuccess(204), assertCatch = assertError(), use = req => req } = options
    test(`PATCH ${this.testPath}/:id`, async () => {
      let item
      if (data) {
        const req = request(this.server).post(
          getPathWithContext(this.paths, this.paths.length - 1, context.items)
        )
        let res
        if (isFunction(data)) {
          res = await data({req})
        } else {
          res = await req.send(data)
        }
        item = res.body
      } else {
        item = last(context.items)
      }

      const response = this.applyMiddleware(use, request(this.server).del(
        `${getPathWithContext(this.paths, this.paths.length - 1, context.items)}/${item.id}`
      ))
      await response.then(res => {
        assert(res, { success: assertSuccess(204) })
      }).catch(assertCatch)
    })
    return this
  }
  crud (options) {
    return this.create().read().update(null, options).destroy()
  }
}

function restful (...args) {
  return new ResourceTester(...args)
}

module.exports = {
  restful,
  request
}
<commit_msg>test refactor<commit_after>const request = require('supertest')
const { last, isArray, isFunction, forIn } = require('lodash')
const { expect, test, afterAll, beforeEach } = global
const Promise = require('bluebird')
const context = {}

function getPathWithContext (paths, index, items) {
  index = parseInt(index)
  let path = ''
  for (var i = 0; i <= index; i++) {
    if (i === index) {
      path += `${paths[index]}`
    } else {
      path += `${paths[i]}/${items[i].id}`
    }
  }
  return path
}

function assertSuccess (status, attrs = null) {
  return (res, strict = true) => {
    expect(res.status).toBe(status)
    if (attrs && strict) {
      forIn(attrs, (v, k) => {
        expect(res.body[k]).toEqual(v)
      })
    }
  }
}

function assertError () {
  return e => { throw e }
}

class ResourceTester {
  constructor (server, paths, options) {
    options = Object.assign({
      teardown: true
    }, options)
    this.server = server
    this.middlewares = []
    this.paths = !isArray(paths) ? [paths] : paths
    if (options.teardown) {
      afterAll(async () => {
        await Promise.promisify(this.server.close).call(this.server)
      })
    }
  }
  get testPath () { return this.paths.join('/:id') }
  use (...middlewares) {
    this.middlewares = this.middlewares.concat(middlewares)
    return this
  }
  async setup (setup) {
    beforeEach(async () => {
      const utils = {
        request: async (nestedDatas, options = {}) => {
          const { use = req => req } = options
          const middleares = [ use ]
          const items = []
          const responses = []
          for (const index in nestedDatas) {
            const data = nestedDatas[index]
            const response = middleares.reduce(
              (req, middleware) => {
                middleware(req)
                return req
              },
              request(this.server).post(getPathWithContext(this.paths, index, items))
            ).send(data)
            items.push((await response).body)
            responses.push(response)
          }
          return { items, responses }
        }
      }
      setup = isFunction(setup) ? setup : async ({request}) => {
        return await request(!isArray(setup) ? [setup] : setup)
      }
      Object.assign(context, await setup(utils))
    })

    return this
  }
  applyMiddleware (middleware, req) {
    const middlewares = [ middleware ].concat(this.middlewares)
    return middlewares.reduce((req, middleware) => {
      middleware(req)
      return req
    }, req)
  }
  create (data = null, options = {}) {
    options = isFunction(options) ? {assert: options} : options
    const { assert = assertSuccess(201, data), assertCatch = assertError(), use = req => req } = options
    test(`POST ${this.testPath}`, async () => {
      const response = !data
        ? last(context.responses)
        : this.applyMiddleware(use, request(this.server).post(
          getPathWithContext(this.paths, this.paths.length - 1, context.items)
        )).send(data)
      await response.then(res => {
        assert(res, { success: assertSuccess(201, data) })
      }).catch(assertCatch)
    })
    return this
  }
  read (data = null, options = {}) {
    this.list(data, options)
    this.item(data, options)
    return this
  }
  list (data = null, options = {}) {
    options = isFunction(options) ? {assert: options} : options
    const {
      assert = assertSuccess(200),
      assertCatch = assertError(),
      use = req => req,
      prepare = true
    } = options
    test(`LIST ${this.testPath}`, async () => {
      if (prepare) {
        if (data) {
          const req = request(this.server).post(
            getPathWithContext(this.paths, this.paths.length - 1, context.items)
          )
          if (isFunction(data)) {
            await data({req})
          } else {
            await req.send(data)
          }
        }
      }
      const response = this.applyMiddleware(use, request(this.server).get(
        getPathWithContext(this.paths, this.paths.length - 1, context.items)
      ))
      await response.then(res => {
        assert(res, { success: assertSuccess(200) })
      }).catch(assertCatch)
    })
    return this
  }
  item (data = null, options = {}) {
    options = isFunction(options) ? {assert: options} : options
    const {
      assert = assertSuccess(200),
      assertCatch = assertError(),
      use = req => req,
      prepare = true
    } = options
    test(`GET ${this.testPath}/:id`, async () => {
      let item
      if (prepare) {
        if (data) {
          const req = request(this.server).post(
            getPathWithContext(this.paths, this.paths.length - 1, context.items)
          )
          let res
          if (isFunction(data)) {
            res = await data({req})
          } else {
            res = await req.send(data)
          }
          item = res.body
        } else {
          item = last(context.items)
        }
      } else {
        item = data
      }
      const response = this.applyMiddleware(use, request(this.server).get(
        `${getPathWithContext(this.paths, this.paths.length - 1, context.items)}/${item.id}`
      ))
      await response.then(res => {
        assert(res, { success: assertSuccess(200), item })
      }).catch(assertCatch)
    })
    return this
  }
  update (data = null, options = {}) {
    options = isFunction(options) ? {assert: options} : options
    const {
      assert = assertSuccess(202),
      assertCatch = assertError(),
      use = req => req,
      patch,
      prepare = true
    } = options
    test(`PATCH ${this.testPath}/:id`, async () => {
      let item
      if (prepare) {
        if (data) {
          const req = request(this.server).post(
            getPathWithContext(this.paths, this.paths.length - 1, context.items)
          )
          let res
          if (isFunction(data)) {
            res = await data({req})
          } else {
            res = await req.send(data)
          }
          item = res.body
        } else {
          item = last(context.items)
        }
      } else {
        item = data
      }

      const response = this.applyMiddleware(use, request(this.server).patch(
        `${getPathWithContext(this.paths, this.paths.length - 1, context.items)}/${item.id}`
      )).send(patch)
      await response.then(res => {
        assert(res, { success: assertSuccess(202, patch) })
      }).catch(assertCatch)
    })
    return this
  }
  destroy (data = null, options = {}) {
    options = isFunction(options) ? {assert: options} : options
    const {
      assert = assertSuccess(204),
      assertCatch = assertError(),
      use = req => req,
      prepare = true
    } = options
    test(`PATCH ${this.testPath}/:id`, async () => {
      let item
      if (prepare) {
        if (data) {
          const req = request(this.server).post(
            getPathWithContext(this.paths, this.paths.length - 1, context.items)
          )
          let res
          if (isFunction(data)) {
            res = await data({req})
          } else {
            res = await req.send(data)
          }
          item = res.body
        } else {
          item = last(context.items)
        }
      } else {
        item = data
      }

      const response = this.applyMiddleware(use, request(this.server).del(
        `${getPathWithContext(this.paths, this.paths.length - 1, context.items)}/${item.id}`
      ))
      await response.then(res => {
        assert(res, { success: assertSuccess(204) })
      }).catch(assertCatch)
    })
    return this
  }
  crud (options) {
    return this.create().read().update(null, options).destroy()
  }
}

function restful (...args) {
  return new ResourceTester(...args)
}

module.exports = {
  restful,
  request
}
<|endoftext|>


<commit_before>var util = require("util");

var Widget = require("./widget");

var Text = module.exports = function Text(config) {
  if (!config) { config = {}; }

  Widget.call(this, config);

  this.align = config.align || "left";
  this.content = config.content || "";
};
util.inherits(Text, Widget);

Text.prototype.reflow = function reflow() {
  this.moveTo([0, 0]);
  this.write((new Array(this.width)).join(" "));

  if (this.align === "left") {
    this.moveTo([0, 0]);
  } else if (this.align === "right") {
    this.moveTo([0, this.width - this.content.length]);
  } else if (this.align === "center") {
    this.moveTo([0, this.width / 2 - this.content.length / 2]);
  }

  this.write(this.content);
};
<commit_msg>fix height > 1 text widget clearing<commit_after>var util = require("util");

var Widget = require("./widget");

var Text = module.exports = function Text(config) {
  if (!config) { config = {}; }

  Widget.call(this, config);

  this.align = config.align || "left";
  this.content = config.content || "";
};
util.inherits(Text, Widget);

Text.prototype.reflow = function reflow() {
  for (var i=0;i<this.height;++i) {
    this.moveTo([i, 0]);
    this.write((new Array(this.width)).join(" "));
  }

  if (this.align === "left") {
    this.moveTo([0, 0]);
  } else if (this.align === "right") {
    this.moveTo([0, this.width - this.content.length]);
  } else if (this.align === "center") {
    this.moveTo([0, this.width / 2 - this.content.length / 2]);
  }

  this.write(this.content);
};
<|endoftext|>


<commit_before>const {fromJS, Map} = require('immutable')
const {partial, predicate} = require('../core/fn')
const {isOfType, isBeforeDate} = require('./utils')
const {getTotalValueForTheGivenPrice} = require('./portfolioValue')

const getTxnsOnDate = (txns, day, asset) => txns
  .filter(
    predicate(
      partial(isOfType, asset),
      partial(isBeforeDate, day))
    )

// Gets all prices for the last 30 days for the given symbol i.e. ETH
// and returns the portfolio values for each day
// i.e. Price[] Transaction[Id, Transaction] Symbol -> {day, value}
const getPortfolioValueForAsset = (priceList, txns, asset) =>
  priceList.map(p => {
    const {day, price} = p.toJS();

    return fromJS({
      day,
      value: {
        // change: getChangeAfterDate(txns, asset, day, price),
        // cash: getCashAfterDate(txns, asset, day),
        totalValue: getTotalValueForTheGivenPrice(
          getTxnsOnDate(txns, day, asset),
          asset,
          price
        )
      }
    })
  })

// returns a Map with keys for each asset and the entries
// for each day as well as the portfolio value on that date
// e.g. {[id]: Transaction} {ETH: Price[]} -> { ETH: [{day: 123, value: 2000}], BTC:  [{day: 123, value: 2000}]}
const calculateHistoricPortfolioValues = ({txns, prices}) => prices.reduce(
  (acc, priceList, asset) => acc.set(
    asset,
    getPortfolioValueForAsset(priceList, txns, asset),
  ),
  Map()
)

module.exports = {calculateHistoricPortfolioValues}
<commit_msg>do not filter by asset type when calculating the historic value<commit_after>const {fromJS, Map} = require('immutable')
const {partial} = require('../core/fn')
const {isOfType, isBeforeDate} = require('./utils')
const {getTotalValueForTheGivenPrice} = require('./portfolioValue')

const getTxnsOnDate = (txns, day) => txns.filter(partial(isBeforeDate, day))

// Gets all prices for the last 30 days for the given asset i.e. ETH
// and returns the portfolio values for each day
// i.e. Price[] Transaction[Id, Transaction] Asset -> {day, value}
const getPortfolioValueForAsset = (priceList, txns, asset) =>
  priceList.map(p => {
    const {day, price} = p.toJS();

    return fromJS({
      day,
      value: {
        // change: getChangeAfterDate(txns, asset, day, price),
        // cash: getCashAfterDate(txns, asset, day),
        totalValue: getTotalValueForTheGivenPrice(
          getTxnsOnDate(txns, day),
          asset,
          price
        )
      }
    })
  })

// returns a Map with keys for each asset and the entries
// for each day as well as the portfolio value on that date
// e.g. {[id]: Transaction} {ETH: Price[]} -> { ETH: [{day: 123, value: 2000}], BTC:  [{day: 123, value: 2000}]}
const calculateHistoricPortfolioValues = ({txns, prices}) => prices.reduce(
  (acc, priceList, asset) => acc.set(
    asset,
    getPortfolioValueForAsset(priceList, txns, asset),
  ),
  Map()
)

module.exports = {calculateHistoricPortfolioValues}
<|endoftext|>


<commit_before>module.exports = function () {

    var tourHandler = document.querySelector('.js-handler--restart-tour');

    tourHandler.addEventListener('click', restartTour, false);

    var tour = new Shepherd.Tour({
        defaults: {
            classes: 'shepherd-theme-arrows',
            scrollTo: false
        }
    });

    tour.addStep('intro', {
        text: 'This is a guided introduction to Kreator.js
 It will show you how to control and style the content
 You can cancel if you know what to do or click start
',
        buttons: [
            {
                text: 'Cancel',
                action: finishTour
            },
            {
                text: 'Start',
                action: tour.next
            }
        ]
    })

    tour.addStep('example-step', {
        text: 'This is the main control for the content',
        attachTo: '.topmenu',
        buttons: [{
            text: 'Next',
            action: tour.next
        }],
        tetherOptions: {
            attachment: 'bottom center',
            targetAttachment: 'top center'
        }
    });

    tour.addStep('example-step', {
        text: 'Set the text to bold, italic or underlined',
        attachTo: '.js-handler--style-button',
        tetherOptions: {
            attachment: 'bottom left',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Make a bullet list',
        attachTo: '.js-handler--list-button',
        tetherOptions: {
            attachment: 'bottom left',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Align left, center or right  ',
        attachTo: '.js-handler--align',
        tetherOptions: {
            attachment: 'bottom left',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Align left, center or right',
        attachTo: '.js-handler--align',
        tetherOptions: {
            attachment: 'bottom left',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Set the text color',
        attachTo: '.js-handler--color',
        tetherOptions: {
            attachment: 'bottom left',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Add slide',
        attachTo: '.js-handler--add-slide-right',
        tetherOptions: {
            attachment: 'top left',
            targetAttachment: 'top right'
        }
    });

    tour.addStep('example-step', {
        text: 'Presentation name',
        attachTo: '.js-handler--presentation-name',
        tetherOptions: {
            attachment: 'top right',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Change the theme',
        attachTo: '.js-handler--theme-selector',
        tetherOptions: {
            attachment: 'top right',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Download when you are all done',
        attachTo: '.js-handler--download',
        tetherOptions: {
            attachment: 'top right',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'That is all. I hope you make a great presentation!',
        buttons: [{
            'text': 'Start writing',
            action: finishTour
        }]
    });

    if (!localStorage.getItem('tour')) tour.start();

    function finishTour() {
        localStorage.setItem('tour', 'complete');
        tour.hide();
    }

    function restartTour() {
        tour.start();
    }
}
<commit_msg>Remove steps that were related to editing<commit_after>module.exports = function () {

    var tourHandler = document.querySelector('.js-handler--restart-tour');

    tourHandler.addEventListener('click', restartTour, false);

    var tour = new Shepherd.Tour({
        defaults: {
            classes: 'shepherd-theme-arrows',
            scrollTo: false
        }
    });

    tour.addStep('intro', {
        text: 'This is a guided introduction to Kreator.js
 It will show you how to control and style the content
 You can cancel if you know what to do or click start
',
        buttons: [
            {
                text: 'Cancel',
                action: finishTour
            },
            {
                text: 'Start',
                action: tour.next
            }
        ]
    })

    tour.addStep('example-step', {
        text: 'Add slide',
        attachTo: '.js-handler--add-slide-right',
        tetherOptions: {
            attachment: 'top left',
            targetAttachment: 'top right'
        }
    });

    tour.addStep('example-step', {
        text: 'Presentation name',
        attachTo: '.js-handler--presentation-name',
        tetherOptions: {
            attachment: 'top right',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Change the theme',
        attachTo: '.js-handler--theme-selector',
        tetherOptions: {
            attachment: 'top right',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'Download when you are all done',
        attachTo: '.js-handler--download',
        tetherOptions: {
            attachment: 'top right',
            targetAttachment: 'top left'
        }
    });

    tour.addStep('example-step', {
        text: 'That is all. I hope you make a great presentation!',
        buttons: [{
            'text': 'Start writing',
            action: finishTour
        }]
    });

    if (!localStorage.getItem('tour')) tour.start();

    function finishTour() {
        localStorage.setItem('tour', 'complete');
        tour.hide();
    }

    function restartTour() {
        tour.start();
    }
}
<|endoftext|>


<commit_before>var git = require( '../' )
  , events = require( 'events' );

var _Tree = function( obj, tree ) {
  var self = {};
  if ( obj instanceof git.raw.Repo && tree instanceof git.raw.Tree ) {
    self.repo = obj;
    self.tree = tree;
  }
  else if( obj instanceof git.raw.Repo ) {
    self.repo = obj;
    self.tree = new git.raw.Tree( tree );
  }
  else if ( obj instanceof git.raw.Tree ) {
    self.tree = obj;
  }
  else {
    self.tree = new git.raw.Tree();
  }

  Object.defineProperty( self, 'length', {
    get: function() {
      return self.tree.entryCount();
    },
    enumerable: true
  });

  self.walk = function( repo ) {
    var entry
      , i
      , len = self.length
      , repo = repo || self.repo
      , event = new events.EventEmitter();

    function next(i) {
      var dir;
      var tree;

      entry = git.entry( repo );

      self.tree.entryByIndex(entry.entry, i, function() {
        if(entry.isFile()) {
          event.emit( 'entry', i, entry );
        }
        else {
          dir = entry.name;
          tree = entry.tree();

          !tree.error && tree.walk( repo ).on( 'entry', function( i, entry ) {
            entry.dir += dir + '/';
            event.emit( 'entry', i, entry );
          });
        }

        if( i<len-1 ) {
          next(i=i+1);
        }
        else {
          event.emit( 'end' );
        }
      });
    }

    next(0);

    return event;
  };

  self.entry = function( name, callback ) {
    if( !callback ) { return; }

    var entry = git.entry( self.repo );

    var path = name.split( '/' );
    if( path.length === 1 ) {
      self.tree.entryByName( entry.entry, path[0], function( valid ) {
        callback( valid ? entry : undefined );
      });
    }
    else {
      function recurse( tree ) {
        var name = path.shift();
        var tree = tree || self.tree;

        tree.entryByName( entry.entry, name, function( valid ) {
          if( !path.length ) {
            callback( valid ? entry : undefined );
          }
          else {
            recurse( entry.tree().tree );
          }
        });
      }

      recurse();
    }
  };

  return self;
};

exports.tree = _Tree;
<commit_msg>fixes bugs with tree not returning a valid commit<commit_after>var git = require( '../' )
  , events = require( 'events' );

var _Tree = function( obj, tree ) {
  var self = {};
  if ( obj instanceof git.raw.Repo && tree instanceof git.raw.Tree ) {
    self.repo = obj;
    self.tree = tree;
  }
  else if( obj instanceof git.raw.Repo ) {
    self.repo = obj;
    self.tree = new git.raw.Tree( tree );
  }
  else if ( obj instanceof git.raw.Tree ) {
    self.tree = obj;
  }
  else {
    self.tree = new git.raw.Tree();
  }

  Object.defineProperty( self, 'length', {
    get: function() {
      return self.tree.entryCount();
    },
    enumerable: true
  });

  self.walk = function( repo ) {
    var entry
      , i
      , len = self.length
      , repo = repo || self.repo
      , event = new events.EventEmitter();

    function next(i) {
      var dir;
      var tree;

      entry = git.entry( repo );

      self.tree.entryByIndex(entry.entry, i, function() {
        if(entry.isFile()) {
          event.emit( 'entry', i, entry );
        }
        else {
          dir = entry.name;
          tree = entry.tree();

          !tree.error && tree.walk( repo ).on( 'entry', function( i, entry ) {
            entry.dir += dir + '/';
            event.emit( 'entry', i, entry );
          });
        }

        if( i<len-1 ) {
          next(i=i+1);
        }
        else {
          event.emit( 'end' );
        }
      });
    }

    next(0);

    return event;
  };

  self.entry = function( name, callback ) {
    if( !callback ) { return; }

    var entry = git.entry( self.repo );

    var path = name.split( '/' );
    if( path.length === 1 ) {
      self.tree.entryByName( entry.entry, path[0], function( valid ) {
        callback( valid ? entry : undefined );
      });
    }
    else {
      function recurse( tree ) {
        var name = path.shift();
        var tree = tree || self.tree;

        tree.entryByName( entry.entry, name, function( valid ) {
          if( !path.length ) {
            callback( valid ? entry : undefined );
          }
          else {
            if (valid) {
              recurse( entry.tree().tree );
            }
            else {
              callback(undefined);
            }
          }
        });
      }

      recurse();
    }
  };

  return self;
};

exports.tree = _Tree;
<|endoftext|>


<commit_before>/*
 * tune
 * https://github.com/shama/tune
 *
 * Copyright (c) 2012 Kyle Robinson Young
 * Licensed under the MIT license.
 */

'use strict';

// libs
var util = require('util');
var plucky = require('plucky');

// class
var Tune = function(notes, opts) {
  opts = opts || {};

  // duration of note
  this.duration = opts.duration || 1/4;

  // repeat the tune
  this.repeat = opts.repeat || true;

  // volume knob
  this.volume = opts.volume || 1;

  // last octave set
  this._octave = 4;

  // parse notes
  var measures = this._parseNotes(notes);

  // lame repeat, todo: add repeat to last measure instead
  if (this.repeat) measures.push(function(t, clip) { clip.go(0); });

  return plucky(measures);
};

// exports
var tune = module.exports = function(notes, opts) {
  return new Tune(notes, opts);
};

// expose class
tune.Tune = Tune;

// Return Hz of steps +/- C4
// Hz = C4 * ( 2^1/12 )^steps
Tune.prototype._hz = function(steps) {
  return 261.63 * Math.pow(Math.pow(2, 1/12), steps || 0);
};

// parses string|array of notes into Hz
Tune.prototype._parseNotes = function(notes) {
  var _this = this;
  if (typeof notes === 'string') notes = [notes];
  notes.forEach(function(note, i) {
    notes[i] = util.isArray(note) ? _this._parseNotes(note) : _this._parseNote(note);
  });
  return notes;
};

// parse a note (C4, C#4, Ab5) to Hz
Tune.prototype._parseNote = function(note) {
  var x,
    _this = this,
    notes = 'A A# B C C# D D# E F F# G G#'.split(' '),
    a = (x = note.match(/^[a-z]/i)) ? x[0].toUpperCase() : 'C',
    n = (x = note.slice(1).match(/[0-9]/i)) ? x[0] : _this._octave,
    m = (x = note.slice(1).match(/#|b/i)) ? x[0] : '';
  if (m === 'b') {
    a = notes[notes.indexOf(a) - 1];
    m = '';
  }
  _this._octave = Number(n) || _this._octave;
  var steps = (notes.indexOf(a + m) - notes.indexOf('C')) + ((n - 4) * notes.length);
  return function(t, clip) {
    if (t > _this.duration) clip.end();
    return _this.volume * (Math.sin((2 * Math.PI) * _this._hz(steps) * t));
  };
};
<commit_msg>Add mute notes<commit_after>/*
 * tune
 * https://github.com/shama/tune
 *
 * Copyright (c) 2012 Kyle Robinson Young
 * Licensed under the MIT license.
 */

'use strict';

// libs
var util = require('util');
var plucky = require('plucky');

// class
var Tune = function(notes, opts) {
  opts = opts || {};

  // duration of note
  this.duration = opts.duration || 1/4;

  // repeat the tune
  this.repeat = opts.repeat || true;

  // volume knob
  this.volume = opts.volume || 1;

  // last octave set
  this._octave = 4;

  // parse notes
  var measures = this._parseNotes(notes);

  // lame repeat, todo: add repeat to last measure instead
  if (this.repeat) measures.push(function(t, clip) { clip.go(0); });

  return plucky(measures);
};

// exports
var tune = module.exports = function(notes, opts) {
  return new Tune(notes, opts);
};

// expose class
tune.Tune = Tune;

// Return Hz of steps +/- C4
// Hz = C4 * ( 2^1/12 )^steps
Tune.prototype._hz = function(steps) {
  return 261.63 * Math.pow(Math.pow(2, 1/12), steps || 0);
};

// parses string|array of notes into Hz
Tune.prototype._parseNotes = function(notes) {
  var _this = this;
  if (typeof notes === 'string') notes = [notes];
  notes.forEach(function(note, i) {
    notes[i] = util.isArray(note) ? _this._parseNotes(note) : _this._parseNote(note);
  });
  return notes;
};

// parse a note (C4, C#4, Ab5) to Hz
Tune.prototype._parseNote = function(note) {
  var x,
    _this = this,
    notes = 'A A# B C C# D D# E F F# G G#'.split(' '),
    a = (x = note.match(/^[a-z]/i)) ? x[0].toUpperCase() : 'C',
    n = (x = note.slice(1).match(/[0-9]/i)) ? x[0] : _this._octave,
    m = (x = note.slice(1).match(/#|b/i)) ? x[0] : '';
  if (m === 'b') {
    a = notes[notes.indexOf(a) - 1];
    m = '';
  }
  _this._octave = Number(n) || _this._octave;
  var steps = (notes.indexOf(a + m) - notes.indexOf('C')) + ((n - 4) * notes.length);
  return function(t, clip) {
    if (t > _this.duration) clip.end();
    if (note === '.') return 0;
    return _this.volume * (Math.sin((2 * Math.PI) * _this._hz(steps) * t));
  };
};
<|endoftext|>


<commit_before>var P = require('bluebird');
var async = require('async');
var checkPrivilege = require('./privilege_check');
var newGithub = require('./new_github');
var users = require('./db').get('users');
P.promisifyAll(users);

/**
 * Gets all of the users that the user hasn't been followed by.
 */
function findNotFollowedBy(gh, dbuser) {
  // Get followers of user
  var followedBy = dbuser.followedBy || [];

  // Find users where their login isn't one of those followedBy
  return users.findAsync({
    login: {
      $nin: followedBy
    }
  }).then(function(dbNotFollowing) {
    return new P(function(resolve, reject) {
      if (!dbNotFollowing) return;

      // These are the users that are not following in the DB.
      var notFollowing = [];
      async.each(dbNotFollowing, function(userObj, done) {
        if (gh.login === userObj.login) return done(); // Skip if same user

        var ugh = newGithub(userObj.token);
        var getFollowUser = P.promisify(ugh.user.getFollowUser, ugh.user);
        getFollowUser({
          user: gh.login
        }).then(function(res) {
          done();
        }, function() {
          notFollowing.push(userObj.login);
          done();
        });

      }, function(err) {
        if (err) return reject(err);
        resolve(notFollowing);
      });
    });
  });
}

function getUser(login) {
  return checkPrivilege(login).then(function(privilege) {

    return users.findOneAsync({
      login: login
    }).then(function(user) {

      var gh = newGithub(user.token);
      gh.login = user.login;

      users.findAsync({
        followedBy: login
      }).then(function(following) {

        findNotFollowedBy(gh, user).then(function(notFollowedBy) {

          var followerCt = user.followedBy ? user.followedBy.length : 0;
          var remaining = privilege.count - followerCt;
          var amount = Math.min(notFollowedBy.length, remaining);
          if (amount < 0) amount = 0;

          return {
            privilege: privilege,
            following: following,
            amount: amount,
            remaining: remaining,
            followerCt: followerCt,
            user: user
          };

        });
      });
    });
  });
}

module.exports = getUser;
<commit_msg>Use async<commit_after>var P = require('bluebird');
var async = require('async');
var checkPrivilege = require('./privilege_check');
var newGithub = require('./new_github');
var users = require('./db').get('users');
P.promisifyAll(users);
P.promisifyAll(async);

/**
 * Gets all of the users that the user hasn't been followed by.
 */
function findNotFollowedBy(gh, dbuser) {
  // Get followers of user
  var followedBy = dbuser.followedBy || [];

  // Find users where their login isn't one of those followedBy
  return users.findAsync({
    login: {
      $nin: followedBy
    }
  }).then(function(dbNotFollowing) {
    return new P(function(resolve, reject) {
      if (!dbNotFollowing) return;

      // These are the users that are not following in the DB.
      var notFollowing = [];
      return async.eachAsync(dbNotFollowing, function(userObj, done) {
        if (gh.login === userObj.login) return done(); // Skip if same user

        var ugh = newGithub(userObj.token);
        var getFollowUser = P.promisify(ugh.user.getFollowUser, ugh.user);
        getFollowUser({
          user: gh.login
        }).then(function(res) {
          done();
        }, function() {
          notFollowing.push(userObj.login);
          done();
        });

      });
    });
  });
}

function getUser(login) {
  return checkPrivilege(login).then(function(privilege) {

    return users.findOneAsync({
      login: login
    }).then(function(user) {

      var gh = newGithub(user.token);
      gh.login = user.login;

      users.findAsync({
        followedBy: login
      }).then(function(following) {

        findNotFollowedBy(gh, user).then(function(notFollowedBy) {

          var followerCt = user.followedBy ? user.followedBy.length : 0;
          var remaining = privilege.count - followerCt;
          var amount = Math.min(notFollowedBy.length, remaining);
          if (amount < 0) amount = 0;

          return {
            privilege: privilege,
            following: following,
            amount: amount,
            remaining: remaining,
            followerCt: followerCt,
            user: user
          };

        });
      });
    });
  });
}

module.exports = getUser;
<|endoftext|>


<commit_before>// 4: template strings - String.raw
// To do: make all tests pass, leave the asserts unchanged!

describe('on tagged template strings you can use String.raw', function() {

  it('the `raw` property accesses the string as it was entered', function() {
    function firstChar(strings) {
      return strings;
    }
    assert.equal(firstChar`\n`, '\\n');
  });

  it('`raw` can access the backslash of a line-break', function() {
    function firstCharEntered(strings) {
      var lineBreak = strings.raw[0];
      return lineBreak;
    }
    assert.equal(firstCharEntered`\n`, '\\');
  });

  describe('`String.raw` as a static function', function(){

    it('concats the raw strings', function() {
      var expected = '\n';
      assert.equal(String.raw`\n`, expected);
    });

    it('two raw-templates-string-backslashes equal two escaped backslashes', function() {
      const TWO_BACKSLASHES = '\\';
      assert.equal(String.raw`\\`, TWO_BACKSLASHES);
    });

    it('works on unicodes too', function() {
      var smilie = '\u{1F600}';
      var actual = String.raw`\u{1F600}`;
      assert.equal(actual, smilie);
    });

  });
});<commit_msg>Tiny improvements on the `raw` property, kata #4.<commit_after>// 4: template strings - String.raw
// To do: make all tests pass, leave the asserts unchanged!

describe('on tagged template strings you can use the `raw` property like so `s.raw`', function() {

  it('the `raw` property accesses the string as it was entered', function() {
    function firstChar(strings) {
      return strings;
    }
    assert.equal(firstChar`\n`, '\\n');
  });

  it('`raw` can access the backslash of a line-break', function() {
    function firstCharEntered(strings) {
      var lineBreak = strings.raw;
      return lineBreak;
    }
    assert.equal(firstCharEntered`\n`, '\\');
  });

  describe('`String.raw` as a static function', function(){

    it('concats the raw strings', function() {
      var expected = '\n';
      assert.equal(String.raw`\n`, expected);
    });

    it('two raw-templates-string-backslashes equal two escaped backslashes', function() {
      const TWO_BACKSLASHES = '\\';
      assert.equal(String.raw`\\`, TWO_BACKSLASHES);
    });

    it('works on unicodes too', function() {
      var smilie = '\u{1F600}';
      var actual = String.raw`\u{1F600}`;
      assert.equal(actual, smilie);
    });

  });
});<|endoftext|>


<commit_before>'use strict';
var debug    = require('debug')('soundcloud/user');
var filter   = require('lodash.filter');
var is       = require('is_js');
var _request = require('./request');

var getUserByName = function(clientId, name) {
  var regex = new RegExp('/' + name + '$', 'g');
  debug(regex, clientId);

  return _request('users', {
      q: name,
      client_id: clientId
    })
    .then(function(users) {
      if (users.errors) {
        throw new Error(users.errors);
      }

      debug(users.length);

      var user = filter(users, function(user) {
        return regex.test(user.permalink_url);
      });

      debug(user);

      return user[0];
    });
};

var getUserById = function(clientId, id) {
  return _request('users/' + id + '.json', {
    client_id: clientId
  })
  .then(function(results){
    if (results.errors) {
        throw results.errors;
    }
    return results;
  });
};

var SoundCloudUser = function(clientId, name) {
  this.clientId = clientId;

  if (is.number(name)) {
    this.user = getUserById(clientId, name);
  } else {
    this.user = getUserByName(clientId, name);
  }

  this.getUserInfo = function(type) {
    var self = this;
    return this.user
      .then(function(user) {
        debug(user);
        var id = user.id;
        return _request('users/' + id + '/' + type + '.json', {
          client_id: self.clientId
        });
      })
      .then(function(results) {
        debug(results);
        return results;
      });
  };
};

SoundCloudUser.prototype.details = function() {
  return this.user
    .then(function(user) {
      return user;
    });
};

SoundCloudUser.prototype.tracks = function() {
  return this.getUserInfo('tracks');
};

SoundCloudUser.prototype.playlists = function() {
  return this.getUserInfo('playlists');
};

SoundCloudUser.prototype.followings = function() {
  return this.getUserInfo('followings');
};

SoundCloudUser.prototype.followers = function() {
  return this.getUserInfo('followers');
};

SoundCloudUser.prototype.comments = function() {
  return this.getUserInfo('comments');
};

SoundCloudUser.prototype.favorites = function() {
  return this.getUserInfo('favorites');
};

SoundCloudUser.prototype.groups = function() {
  return this.getUserInfo('groups');
};

SoundCloudUser.prototype.webProfiles = function() {
  return this.getUserInfo('web-profiles');
};

module.exports = SoundCloudUser;<commit_msg>add extra params for pagination related values<commit_after>'use strict';
var debug    = require('debug')('soundcloud/user');
var filter   = require('lodash.filter');
var is       = require('is_js');
var _request = require('./request');

var getUserByName = function(clientId, name) {
  var regex = new RegExp('/' + name + '$', 'g');
  debug(regex, clientId);

  return _request('users', {
      q: name,
      client_id: clientId
    })
    .then(function(users) {
      if (users.errors) {
        throw new Error(users.errors);
      }

      debug(users.length);

      var user = filter(users, function(user) {
        return regex.test(user.permalink_url);
      });

      debug(user);

      return user[0];
    });
};

var getUserById = function(clientId, id) {
  return _request('users/' + id + '.json', {
    client_id: clientId
  })
  .then(function(results){
    if (results.errors) {
        throw results.errors;
    }
    return results;
  });
};

var SoundCloudUser = function(clientId, name) {
  this.clientId = clientId;

  if (is.number(name)) {
    this.user = getUserById(clientId, name);
  } else {
    this.user = getUserByName(clientId, name);
  }

  this.getUserInfo = function(type, params) {
    var self = this;
    return this.user
      .then(function(user) {
        debug(user);
        var id = user.id;
        params = params || {};
        params.client_id = self.clientId;

        return _request('users/' + id + '/' + type + '.json', params);
      })
      .then(function(results) {
        debug(results);
        return results;
      });
  };
};

SoundCloudUser.prototype.details = function() {
  return this.user
    .then(function(user) {
      return user;
    });
};

SoundCloudUser.prototype.tracks = function(params) {
  return this.getUserInfo('tracks', params);
};

SoundCloudUser.prototype.playlists = function(params) {
  return this.getUserInfo('playlists', params);
};

SoundCloudUser.prototype.followings = function(params) {
  return this.getUserInfo('followings', params);
};

SoundCloudUser.prototype.followers = function(params) {
  return this.getUserInfo('followers', params);
};

SoundCloudUser.prototype.comments = function(params) {
  return this.getUserInfo('comments', params);
};

SoundCloudUser.prototype.favorites = function(params) {
  return this.getUserInfo('favorites', params);
};

SoundCloudUser.prototype.groups = function(params) {
  return this.getUserInfo('groups', params);
};

SoundCloudUser.prototype.webProfiles = function(params) {
  return this.getUserInfo('web-profiles', params);
};

module.exports = SoundCloudUser;
<|endoftext|>


<commit_before>import hash from './hash';

const parameters = process.argv.slice(2);

console.log(`sha512#${hash('sha512', parameters[0], parameters[1])}`);
<commit_msg>removed unnecessary user script<commit_after><|endoftext|>