Comparing version 0.4.2 to 0.4.3
486
chance.js
@@ -1,2 +0,2 @@ | ||
// Chance.js 0.4.2 | ||
// Chance.js 0.4.3 | ||
// http://chancejs.com | ||
@@ -8,2 +8,10 @@ // (c) 2013 Victor Quinn | ||
// Constants | ||
var MAX_INT = 9007199254740992; | ||
var MIN_INT = -MAX_INT; | ||
var NUMBERS = '0123456789'; | ||
var CHARS_LOWER = 'abcdefghijklmnopqrstuvwxyz'; | ||
var CHARS_UPPER = CHARS_LOWER.toUpperCase(); | ||
var HEX_POOL = NUMBERS + "abcdef"; | ||
// Constructor | ||
@@ -29,12 +37,33 @@ var Chance = function (seed) { | ||
// Random helper functions | ||
function initOptions(options, defaults) { | ||
options || (options = {}); | ||
if (!defaults) { | ||
return options; | ||
} | ||
for (var i in defaults) { | ||
if (typeof options[i] === 'undefined') { | ||
options[i] = defaults[i]; | ||
} | ||
} | ||
return options; | ||
} | ||
function testRange(test, errorMessage) { | ||
if (test) { | ||
throw new RangeError(errorMessage); | ||
} | ||
} | ||
// -- Basics -- | ||
Chance.prototype.bool = function (options) { | ||
options = options || {}; | ||
// likelihood of success (true) | ||
options.likelihood = (typeof options.likelihood !== "undefined") ? options.likelihood : 50; | ||
options = initOptions(options, {likelihood : 50}); | ||
if (options.likelihood < 0 || options.likelihood > 100) { | ||
throw new RangeError("Chance: Likelihood accepts values from 0 to 100."); | ||
} | ||
testRange( | ||
options.likelihood < 0 || options.likelihood > 100, | ||
"Chance: Likelihood accepts values from 0 to 100." | ||
); | ||
@@ -44,28 +73,79 @@ return this.random() * 100 < options.likelihood; | ||
// NOTE the max and min are INCLUDED in the range. So: | ||
// | ||
// chance.natural({min: 1, max: 3}); | ||
// | ||
// would return either 1, 2, or 3. | ||
Chance.prototype.character = function (options) { | ||
options = initOptions(options); | ||
Chance.prototype.natural = function (options) { | ||
options = options || {}; | ||
options.min = (typeof options.min !== "undefined") ? options.min : 0; | ||
// 9007199254740992 (2^53) is the max integer number in JavaScript | ||
// See: http://vq.io/132sa2j | ||
options.max = (typeof options.max !== "undefined") ? options.max : 9007199254740992; | ||
var symbols = "!@#$%^&*()[]", | ||
letters, pool; | ||
if (options.min > options.max) { | ||
throw new RangeError("Chance: Min cannot be greater than Max."); | ||
testRange( | ||
options.alpha && options.symbols, | ||
"Chance: Cannot specify both alpha and symbols." | ||
); | ||
if (options.casing === 'lower') { | ||
letters = CHARS_LOWER; | ||
} else if (options.casing === 'upper') { | ||
letters = CHARS_UPPER; | ||
} else { | ||
letters = CHARS_LOWER + CHARS_UPPER; | ||
} | ||
return Math.floor(this.random() * (options.max - options.min + 1) + options.min); | ||
if (options.pool) { | ||
pool = options.pool; | ||
} else if (options.alpha) { | ||
pool = letters; | ||
} else if (options.symbols) { | ||
pool = symbols; | ||
} else { | ||
pool = letters + NUMBERS + symbols; | ||
} | ||
return pool.charAt(this.natural({max: (pool.length - 1)})); | ||
}; | ||
// Note, wanted to use "float" or "double" but those are both JS reserved words. | ||
// Note, fixed means N OR LESS digits after the decimal. This because | ||
// It could be 14.9000 but in JavaScript, when this is cast as a number, | ||
// the trailing zeroes are dropped. Left to the consumer if trailing zeroes are | ||
// needed | ||
Chance.prototype.floating = function (options) { | ||
var num, range; | ||
options = initOptions(options, {fixed : 4}); | ||
var fixed = Math.pow(10, options.fixed); | ||
testRange( | ||
options.fixed && options.precision, | ||
"Chance: Cannot specify both fixed and precision." | ||
); | ||
var max = MAX_INT / fixed; | ||
var min = -max; | ||
testRange( | ||
options.min && options.fixed && options.min < min, | ||
"Chance: Min specified is out of range with fixed. Min should be, at least, " + min | ||
); | ||
testRange( | ||
options.max && options.fixed && options.max > max, | ||
"Chance: Max specified is out of range with fixed. Max should be, at most, " + max | ||
); | ||
options = initOptions(options, {min : min, max : max}); | ||
// Todo - Make this work! | ||
// options.precision = (typeof options.precision !== "undefined") ? options.precision : false; | ||
num = this.integer({min: options.min * fixed, max: options.max * fixed}); | ||
var num_fixed = (num / fixed).toFixed(options.fixed); | ||
return parseFloat(num_fixed); | ||
}; | ||
Chance.prototype.integer = function (options) { | ||
var num, range; | ||
options = options || {}; | ||
options.min = (typeof options.min !== "undefined") ? options.min : -9007199254740992; | ||
options.max = (typeof options.max !== "undefined") ? options.max : 9007199254740992; | ||
options = initOptions(options, {min : MIN_INT, max : MAX_INT}); | ||
@@ -78,3 +158,3 @@ // Greatest of absolute value of either max or min so we know we're | ||
do { | ||
num = this.natural({min: 0, max: range}); | ||
num = this.natural({max: range}); | ||
num = this.bool() ? num : num * -1; | ||
@@ -85,11 +165,28 @@ } while (num < options.min || num > options.max); | ||
}; | ||
// NOTE the max and min are INCLUDED in the range. So: | ||
// | ||
// chance.natural({min: 1, max: 3}); | ||
// | ||
// would return either 1, 2, or 3. | ||
Chance.prototype.natural = function (options) { | ||
// 9007199254740992 (2^53) is the max integer number in JavaScript | ||
// See: http://vq.io/132sa2j | ||
options = initOptions(options, {min: 0, max: MAX_INT}); | ||
testRange(options.min > options.max, "Chance: Min cannot be greater than Max."); | ||
return Math.floor(this.random() * (options.max - options.min + 1) + options.min); | ||
}; | ||
Chance.prototype.normal = function (options) { | ||
options = options || {}; | ||
options = initOptions(options, {mean : 0, dev : 1}); | ||
// The Marsaglia Polar method | ||
var s, u, v, norm, | ||
mean = options.mean || 0, | ||
dev = (typeof options.dev !== 'undefined') ? options.dev : 1; | ||
mean = options.mean, | ||
dev = options.dev; | ||
do { | ||
@@ -99,9 +196,9 @@ // U and V are from the uniform distribution on (-1, 1) | ||
v = this.random() * 2 - 1; | ||
s = u * u + v * v; | ||
} while (s >= 1); | ||
// Compute the standard normal variate | ||
norm = u * Math.sqrt(-2 * Math.log(s) / s); | ||
// Shape and scale | ||
@@ -111,75 +208,4 @@ return dev * norm + mean; | ||
// Note, wanted to use "float" or "double" but those are both JS reserved words. | ||
// Note, fixed means N OR LESS digits after the decimal. This because | ||
// It could be 14.9000 but in JavaScript, when this is cast as a number, | ||
// the trailing zeroes are dropped. Left to the consumer if trailing zeroes are | ||
// needed | ||
Chance.prototype.floating = function (options) { | ||
var num, range, buffer; | ||
options = options || {}; | ||
options.fixed = (typeof options.fixed !== "undefined") ? options.fixed : 4; | ||
fixed = Math.pow(10, options.fixed); | ||
if (options.fixed && options.precision) { | ||
throw new RangeError("Chance: Cannot specify both fixed and precision."); | ||
} | ||
if (options.min && options.fixed && options.min < (-9007199254740992 / fixed)) { | ||
throw new RangeError("Chance: Min specified is out of range with fixed. Min" + | ||
"should be, at least, " + (-9007199254740992 / fixed)); | ||
} else if (options.max && options.fixed && options.max > (9007199254740992 / fixed)) { | ||
throw new RangeError("Chance: Max specified is out of range with fixed. Max" + | ||
"should be, at most, " + (9007199254740992 / fixed)); | ||
} | ||
options.min = (typeof options.min !== "undefined") ? options.min : -9007199254740992 / fixed; | ||
options.max = (typeof options.max !== "undefined") ? options.max : 9007199254740992 / fixed; | ||
// Todo - Make this work! | ||
// options.precision = (typeof options.precision !== "undefined") ? options.precision : false; | ||
num = this.integer({min: options.min * fixed, max: options.max * fixed}); | ||
num_fixed = (num / fixed).toFixed(options.fixed); | ||
return parseFloat(num_fixed); | ||
}; | ||
Chance.prototype.character = function (options) { | ||
options = options || {}; | ||
var lower = "abcdefghijklmnopqrstuvwxyz", | ||
upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", | ||
numbers = "0123456789", | ||
symbols = "!@#$%^&*()[]", | ||
letters, pool; | ||
if (options.alpha && options.symbols) { | ||
throw new RangeError("Chance: Cannot specify both alpha and symbols."); | ||
} | ||
if (options.casing === 'lower') { | ||
letters = lower; | ||
} else if (options.casing === 'upper') { | ||
letters = upper; | ||
} else { | ||
letters = lower + upper; | ||
} | ||
if (options.pool) { | ||
pool = options.pool; | ||
} else if (options.alpha) { | ||
pool = letters; | ||
} else if (options.symbols) { | ||
pool = symbols; | ||
} else { | ||
pool = letters + numbers + symbols; | ||
} | ||
return pool.charAt(this.natural({max: (pool.length - 1)})); | ||
}; | ||
Chance.prototype.string = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
@@ -204,17 +230,23 @@ var length = options.length || this.natural({min: 5, max: 20}), | ||
Chance.prototype.pick = function (arr) { | ||
return arr[this.natural({max: arr.length - 1})]; | ||
Chance.prototype.pick = function (arr, count) { | ||
if (!count || count === 1) { | ||
return arr[this.natural({max: arr.length - 1})]; | ||
} else { | ||
return this.shuffle(arr).slice(0, count); | ||
} | ||
}; | ||
Chance.prototype.shuffle = function (arr) { | ||
var new_array = [], | ||
var old_array = arr.slice(0), | ||
new_array = [], | ||
j = 0, | ||
length = Number(arr.length); | ||
length = Number(old_array.length); | ||
for (var i = 0; i < length; i++) { | ||
// Pick a random index from the array | ||
j = this.natural({max: arr.length - 1}); | ||
// Remove it from the array and add it to the new array | ||
new_array[i] = arr.splice(j, 1); | ||
j = this.natural({max: old_array.length - 1}); | ||
// Add it to the new array | ||
new_array[i] = old_array[j]; | ||
// Remove that element from the original array | ||
old_array.splice(j, 1); | ||
} | ||
@@ -230,3 +262,3 @@ | ||
Chance.prototype.paragraph = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
@@ -246,6 +278,6 @@ var sentences = options.sentences || this.natural({min: 3, max: 7}), | ||
Chance.prototype.sentence = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var words = options.words || this.natural({min: 12, max: 18}), | ||
text = '', word_array = []; | ||
text, word_array = []; | ||
@@ -265,3 +297,3 @@ for (var i = 0; i < words; i++) { | ||
Chance.prototype.syllable = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
@@ -273,3 +305,3 @@ var length = options.length || this.natural({min: 2, max: 3}), | ||
text = '', | ||
chr, pool; | ||
chr; | ||
@@ -297,7 +329,8 @@ // I'm sure there's a more elegant way to do this, but this works | ||
Chance.prototype.word = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
if (options.syllables && options.length) { | ||
throw new RangeError("Chance: Cannot specify both syllables AND length."); | ||
} | ||
testRange( | ||
options.syllables && options.length, | ||
"Chance: Cannot specify both syllables AND length." | ||
); | ||
@@ -327,7 +360,7 @@ var syllables = options.syllables || this.natural({min: 1, max: 3}), | ||
// Perhaps make this more intelligent at some point | ||
Chance.prototype.first = function (options) { | ||
Chance.prototype.first = function () { | ||
return this.capitalize(this.word()); | ||
}; | ||
Chance.prototype.last = function (options) { | ||
Chance.prototype.last = function () { | ||
return this.capitalize(this.word()); | ||
@@ -337,3 +370,3 @@ }; | ||
Chance.prototype.name = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
@@ -374,3 +407,3 @@ var first = this.first(), | ||
Chance.prototype.name_prefix = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
return options.full ? | ||
@@ -385,4 +418,31 @@ this.pick(this.name_prefixes()).name : | ||
Chance.prototype.color = function (options) { | ||
function gray(value, delimiter) { | ||
return [value, value, value].join(delimiter || ''); | ||
} | ||
options = initOptions(options, {format: this.pick(['hex', 'shorthex', 'rgb']), grayscale: false}); | ||
var isGrayscale = options.grayscale; | ||
if (options.format === 'hex') { | ||
return '#' + (isGrayscale ? gray(this.hash({length: 2})) : this.hash({length: 6})); | ||
} | ||
if (options.format === 'shorthex') { | ||
return '#' + (isGrayscale ? gray(this.hash({length: 1})) : this.hash({length: 3})); | ||
} | ||
if (options.format === 'rgb') { | ||
if (isGrayscale) { | ||
return 'rgb(' + gray(this.natural({max: 255}), ',') + ')'; | ||
} else { | ||
return 'rgb(' + this.natural({max: 255}) + ',' + this.natural({max: 255}) + ',' + this.natural({max: 255}) + ')'; | ||
} | ||
} | ||
throw new Error('Invalid format provided. Please provide one of "hex", "shorthex", or "rgb"'); | ||
}; | ||
Chance.prototype.domain = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
return this.word() + '.' + (options.tld || this.tld()); | ||
@@ -392,7 +452,7 @@ }; | ||
Chance.prototype.email = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
return this.word() + '@' + (options.domain || this.domain()); | ||
}; | ||
Chance.prototype.fbid = function (options) { | ||
Chance.prototype.fbid = function () { | ||
return '10000' + this.natural({max: 100000000000}).toString(); | ||
@@ -411,7 +471,6 @@ }; | ||
Chance.prototype.ipv6 = function () { | ||
var hex_pool = "0123456789abcdef", | ||
ip_addr = ""; | ||
var ip_addr = ""; | ||
for (var i = 0; i < 8; i++) { | ||
ip_addr += this.string({pool: hex_pool, length: 4}) + ':'; | ||
ip_addr += this.hash({length: 4}) + ':'; | ||
} | ||
@@ -429,3 +488,3 @@ return ip_addr.substr(0, ip_addr.length - 1); | ||
Chance.prototype.twitter = function (options) { | ||
Chance.prototype.twitter = function () { | ||
return '@' + this.word(); | ||
@@ -439,3 +498,3 @@ }; | ||
Chance.prototype.address = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
return this.natural({min: 5, max: 2000}) + ' ' + this.street(options); | ||
@@ -445,11 +504,9 @@ }; | ||
Chance.prototype.areacode = function (options) { | ||
options = options || {}; | ||
options.parens = (typeof options.parens !== "undefined") ? options.parens : true; | ||
// Don't want area codes to start with 1 | ||
var areacode = this.natural({min: 2, max: 9}).toString() + this.natural({min: 10, max: 98}).toString(); | ||
options = initOptions(options, {parens : true}); | ||
// Don't want area codes to start with 1, or have a 9 as the second digit | ||
var areacode = this.natural({min: 2, max: 9}).toString() + this.natural({min: 0, max: 8}).toString() + this.natural({min: 0, max: 9}).toString(); | ||
return options.parens ? '(' + areacode + ')' : areacode; | ||
}; | ||
Chance.prototype.city = function (options) { | ||
options = options || {}; | ||
Chance.prototype.city = function () { | ||
return this.capitalize(this.word({syllables: 3})); | ||
@@ -459,3 +516,3 @@ }; | ||
Chance.prototype.coordinates = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
return this.latitude(options) + ', ' + this.longitude(options); | ||
@@ -465,4 +522,3 @@ }; | ||
Chance.prototype.latitude = function (options) { | ||
options = options || {}; | ||
options.fixed = (typeof options.fixed !== "undefined") ? options.fixed : 5; | ||
options = initOptions(options, {fixed : 5}); | ||
return this.floating({min: -90, max: 90, fixed: options.fixed}); | ||
@@ -472,4 +528,3 @@ }; | ||
Chance.prototype.longitude = function (options) { | ||
options = options || {}; | ||
options.fixed = (typeof options.fixed !== "undefined") ? options.fixed : 5; | ||
options = initOptions(options, {fixed : 5}); | ||
return this.floating({min: 0, max: 180, fixed: options.fixed}); | ||
@@ -479,7 +534,13 @@ }; | ||
Chance.prototype.phone = function (options) { | ||
options = options || {}; | ||
return this.areacode() + ' ' + this.natural({min: 200, max: 999}) + '-' + this.natural({min: 1000, max: 9999}); | ||
options = initOptions(options, {formatted : true}); | ||
if (!options.formatted) { | ||
options.parens = false; | ||
} | ||
var areacode = this.areacode(options).toString(); | ||
var exchange = this.natural({min: 2, max: 9}).toString() + this.natural({min: 0, max: 9}).toString() + this.natural({min: 0, max: 9}).toString(); | ||
var subscriber = this.natural({min: 1000, max: 9999}).toString(); // this could be random [0-9]{4} | ||
return options.formatted ? areacode + ' ' + exchange + '-' + subscriber : areacode + exchange + subscriber; | ||
}; | ||
Chance.prototype.postal = function (options) { | ||
Chance.prototype.postal = function () { | ||
// Postal District | ||
@@ -525,6 +586,5 @@ var pd = this.character({pool: "XVTSRPNKLMHJGECBA"}); | ||
// Initial Letter (Typically Designated by Side of Mississippi River) | ||
options = options || {}; | ||
options.side = ((typeof options.side !== "undefined") ? options.side : "?").toLowerCase(); | ||
options = initOptions(options, {side : "?"}); | ||
var fl = ""; | ||
switch (options.side) { | ||
switch (options.side.toLowerCase()) { | ||
case "east": | ||
@@ -542,3 +602,3 @@ case "e": | ||
} | ||
return fl + this.character({alpha: true, casing: "upper"}) + this.character({alpha: true, casing: "upper"}) + this.character({alpha: true, casing: "upper"}); | ||
@@ -620,3 +680,3 @@ }; | ||
Chance.prototype.street = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
@@ -632,4 +692,4 @@ var street = this.word({syllables: 2}); | ||
Chance.prototype.street_suffix = function (options) { | ||
return this.pick(this.street_suffixes(options)); | ||
Chance.prototype.street_suffix = function () { | ||
return this.pick(this.street_suffixes()); | ||
}; | ||
@@ -684,3 +744,3 @@ | ||
for (var i = 0; i < 5; i++) { | ||
zip += this.natural({min: 0, max: 9}).toString(); | ||
zip += this.natural({max: 9}).toString(); | ||
} | ||
@@ -691,3 +751,3 @@ | ||
for (i = 0; i < 4; i++) { | ||
zip += this.natural({min: 0, max: 9}).toString(); | ||
zip += this.natural({max: 9}).toString(); | ||
} | ||
@@ -703,4 +763,3 @@ } | ||
Chance.prototype.ampm = function (options) { | ||
options = options || {}; | ||
Chance.prototype.ampm = function () { | ||
return this.bool() ? 'am' : 'pm'; | ||
@@ -710,3 +769,3 @@ }; | ||
Chance.prototype.hour = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var max = options.twentyfour ? 24 : 12; | ||
@@ -716,9 +775,8 @@ return this.natural({min: 1, max: max}); | ||
Chance.prototype.minute = function (options) { | ||
options = options || {}; | ||
return this.natural({min: 0, max: 59}); | ||
Chance.prototype.minute = function () { | ||
return this.natural({max: 59}); | ||
}; | ||
Chance.prototype.month = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var month = this.pick(this.months()); | ||
@@ -745,9 +803,7 @@ return options.raw ? month : month.name; | ||
Chance.prototype.second = function (options) { | ||
options = options || {}; | ||
return this.natural({min: 0, max: 59}); | ||
Chance.prototype.second = function () { | ||
return this.natural({max: 59}); | ||
}; | ||
Chance.prototype.timestamp = function (options) { | ||
options = options || {}; | ||
Chance.prototype.timestamp = function () { | ||
return this.natural({min: 1, max: parseInt(new Date().getTime() / 1000, 10)}); | ||
@@ -757,10 +813,9 @@ }; | ||
Chance.prototype.year = function (options) { | ||
options = options || {}; | ||
// Default to current year as min if none specified | ||
options = initOptions(options, {min: new Date().getFullYear()}); | ||
// Default to current year as min if none specified | ||
options.min = (typeof options.min !== "undefined") ? options.min : new Date().getFullYear(); | ||
// Default to one century after current year as max if none specified | ||
options.max = (typeof options.max !== "undefined") ? options.max : options.min + 100; | ||
return this.natural({min: options.min, max: options.max}).toString(); | ||
return this.natural(options).toString(); | ||
}; | ||
@@ -773,7 +828,5 @@ | ||
Chance.prototype.cc = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var type, number, to_generate, type_name, | ||
last = null, | ||
digits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; | ||
var type, number, to_generate, type_name; | ||
@@ -783,3 +836,3 @@ type = (options.type) ? | ||
this.cc_type({ raw: true }); | ||
number = type.prefix; | ||
number = type.prefix.split(""); | ||
to_generate = type.length - type.prefix.length - 1; | ||
@@ -789,11 +842,9 @@ | ||
for (var i = 0; i < to_generate; i++) { | ||
number = number + this.integer({min: 0, max: 9}).toString(); | ||
number.push(this.integer({min: 0, max: 9})); | ||
} | ||
// Generates the last digit according to Luhn algorithm | ||
do { | ||
last = digits.splice(0, 1); | ||
} while (!this.luhn_check(number + last)); | ||
number.push(this.luhn_calculate(number.join(""))); | ||
return number + last; | ||
return number.join(""); | ||
}; | ||
@@ -825,3 +876,3 @@ | ||
Chance.prototype.cc_type = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var types = this.cc_types(), | ||
@@ -849,7 +900,4 @@ type = null; | ||
Chance.prototype.dollar = function (options) { | ||
options = options || {}; | ||
// By default, a somewhat more sane max for dollar than all available numbers | ||
options.max = (typeof options.max !== "undefined") ? options.max : 10000; | ||
options.min = (typeof options.min !== "undefined") ? options.min : 0; | ||
options = initOptions(options, {max : 10000, min : 0}); | ||
@@ -869,3 +917,3 @@ var dollar = this.floating({min: options.min, max: options.max, fixed: 2}).toString(), | ||
Chance.prototype.exp = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var exp = {}; | ||
@@ -887,3 +935,3 @@ | ||
Chance.prototype.exp_month = function (options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
var month, month_int; | ||
@@ -903,3 +951,3 @@ | ||
Chance.prototype.exp_year = function (options) { | ||
Chance.prototype.exp_year = function () { | ||
return this.year({max: new Date().getFullYear() + 10}); | ||
@@ -922,3 +970,3 @@ }; | ||
Chance.prototype.rpg = function (thrown, options) { | ||
options = options || {}; | ||
options = initOptions(options); | ||
if (thrown === null) { | ||
@@ -936,3 +984,3 @@ throw new Error("A type of die roll must be included"); | ||
} | ||
return (typeof options.sum !== 'undefined' && options.sum) ? rolls.reduce(function (p, c, i, a) { return p + c; }) : rolls; | ||
return (typeof options.sum !== 'undefined' && options.sum) ? rolls.reduce(function (p, c) { return p + c; }) : rolls; | ||
} | ||
@@ -943,9 +991,7 @@ }; | ||
Chance.prototype.guid = function () { | ||
var guid_pool = "ABCDEF1234567890", | ||
guid = this.string({pool: guid_pool, length: 8}) + '-' + | ||
this.string({pool: guid_pool, length: 4}) + '-' + | ||
this.string({pool: guid_pool, length: 4}) + '-' + | ||
this.string({pool: guid_pool, length: 4}) + '-' + | ||
this.string({pool: guid_pool, length: 12}); | ||
return guid; | ||
return this.hash({casing: 'upper', length: 8}) + '-' + | ||
this.hash({casing: 'upper', length: 4}) + '-' + | ||
this.hash({casing: 'upper', length: 4}) + '-' + | ||
this.hash({casing: 'upper', length: 4}) + '-' + | ||
this.hash({casing: 'upper', length: 12}); | ||
}; | ||
@@ -955,8 +1001,27 @@ | ||
Chance.prototype.hash = function (options) { | ||
options = options || {}; | ||
var pool = "abcdef1234567890"; | ||
options = initOptions(options, {length : 40, casing: 'lower'}); | ||
var pool = options.casing === 'upper' ? HEX_POOL.toUpperCase() : HEX_POOL; | ||
return this.string({pool: pool, length: options.length}); | ||
}; | ||
options.length = (typeof options.length !== 'undefined') ? options.length : 40; | ||
Chance.prototype.luhn_check = function (num) { | ||
var str = num.toString(); | ||
var checkDigit = +str.substring(str.length - 1); | ||
return checkDigit === this.luhn_calculate(+str.substring(0, str.length - 1)); | ||
}; | ||
return this.string({pool: pool, length: options.length}); | ||
Chance.prototype.luhn_calculate = function (num) { | ||
var digits = num.toString().split("").reverse(); | ||
var sum = 0; | ||
for (var i = 0, l = digits.length; l > i; ++i) { | ||
var digit = +digits[i]; | ||
if (i % 2 === 0) { | ||
digit *= 2; | ||
if (digit > 9) { | ||
digit -= 9; | ||
} | ||
} | ||
sum += digit; | ||
} | ||
return (sum * 9) % 10; | ||
}; | ||
@@ -968,13 +1033,5 @@ | ||
Chance.prototype.luhn_check = function (num) { | ||
var luhnArr = [[0, 2, 4, 6, 8, 1, 3, 5, 7, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]], sum = 0; | ||
num.toString().replace(/\D+/g, "").replace(/[\d]/g, function (c, p, o) { | ||
sum += luhnArr[(o.length - p) & 1][parseInt(c, 10)]; | ||
}); | ||
return (sum % 10 === 0) && (sum > 0); | ||
}; | ||
// -- End Miscellaneous -- | ||
Chance.prototype.VERSION = "0.4.2"; | ||
Chance.prototype.VERSION = "0.4.3"; | ||
@@ -992,3 +1049,3 @@ // Mersenne Twister from https://gist.github.com/banksean/300494 | ||
this.LOWER_MASK = 0x7fffffff; /* least significant r bits */ | ||
this.mt = new Array(this.N); /* the array for the state vector */ | ||
@@ -1131,3 +1188,2 @@ this.mti = this.N + 1; /* mti==N + 1 means mt[N] is not initialized */ | ||
} | ||
})(); |
{ | ||
"name": "chance", | ||
"main": "./chance.js", | ||
"version": "0.4.2", | ||
"version": "0.4.3", | ||
"description": "Chance - Utility library to generate anything random", | ||
@@ -6,0 +6,0 @@ "homepage": "http://chancejs.com", |
@@ -32,2 +32,17 @@ # Chance | ||
### Bower | ||
It can also be used with [Bower](http://bower.io) | ||
bower install chance | ||
then in the HTML of your app: | ||
<!-- Load Chance --> | ||
<script type="text/javascript" src="components/chance/chance.min.js"></script> | ||
<script> | ||
// Use Chance immediately! | ||
alert(chance.string()); | ||
</script> | ||
### RequireJS | ||
@@ -69,19 +84,22 @@ | ||
project : chancejs | ||
repo age : 5 weeks | ||
active : 29 days | ||
commits : 162 | ||
repo age : 6 weeks | ||
active : 35 days | ||
commits : 186 | ||
files : 19 | ||
authors : | ||
125 Victor Quinn 77.2% | ||
11 Tim Petricola 6.8% | ||
10 davmillar 6.2% | ||
5 Michael Cordingley 3.1% | ||
3 qjcg 1.9% | ||
2 dhilipsiva 1.2% | ||
2 path411 1.2% | ||
2 Kevin Garnett 1.2% | ||
1 Richard Anaya 0.6% | ||
1 leesei 0.6% | ||
140 Victor Quinn 75.3% | ||
11 Tim Petricola 5.9% | ||
11 davmillar 5.9% | ||
5 Matt Klaber 2.7% | ||
5 Michael Cordingley 2.7% | ||
3 qjcg 1.6% | ||
2 dhilipsiva 1.1% | ||
2 Kevin Garnett 1.1% | ||
2 path411 1.1% | ||
2 Andreas Koeberle 1.1% | ||
1 Richard Anaya 0.5% | ||
1 leesei 0.5% | ||
1 Ryan Tenney 0.5% | ||
``` | ||
This project is licensed under the [MIT License](http://en.wikipedia.org/wiki/MIT_License) so feel free to hack away :) |
@@ -121,3 +121,3 @@ define(['Chance', 'mocha', 'chai', 'underscore'], function (Chance, mocha, chai, _) { | ||
_(1000).times(function () { | ||
expect(chance.areacode()).to.match(/\(([0-9]{3})\)/); | ||
expect(chance.areacode()).to.match(/^\(([2-9][0-8][0-9])\)$/); | ||
}); | ||
@@ -128,4 +128,4 @@ }); | ||
_(1000).times(function () { | ||
expect(chance.areacode()).to.be.a('string'); | ||
expect(chance.areacode()).to.match(/([0-9]{3})/); | ||
expect(chance.areacode({parens: false})).to.be.a('string'); | ||
expect(chance.areacode({parens: false})).to.match(/^([2-9][0-8][0-9])$/); | ||
}); | ||
@@ -140,5 +140,19 @@ }); | ||
_(1000).times(function () { | ||
expect(chance.phone()).to.match(/\(([0-9]{3})\)?[\-. ]?([0-9]{3})[\-. ]?([0-9]{4})/); | ||
expect(chance.phone()).to.match(/^\(([2-9][0-8][0-9])\)?[\-. ]?([2-9][0-9]{2,2})[\-. ]?([0-9]{4,4})$/); | ||
}); | ||
}); | ||
it('phone({formatted: false}) looks right', function () { | ||
_(1000).times(function () { | ||
expect(chance.phone({formatted : false})).to.be.a('string'); | ||
expect(chance.phone({formatted : false})).to.match(/^[2-9][0-8]\d[2-9]\d{6,6}$/); | ||
}); | ||
}); | ||
it('phone({formatted: false, parens: true}) is unformatted', function () { | ||
_(1000).times(function () { | ||
expect(chance.phone({formatted : false, parens: true})).to.be.a('string'); | ||
expect(chance.phone({formatted : false, parens: true})).to.match(/^[2-9][0-8]\d[2-9]\d{6,6}$/); | ||
}); | ||
}); | ||
}); | ||
@@ -171,3 +185,3 @@ | ||
_(1000).times(function () { | ||
expect(chance.longitude()).to.be.within(0, 180); | ||
expect(chance.longitude()).to.be.within(-180, 180); | ||
}); | ||
@@ -174,0 +188,0 @@ }); |
@@ -18,3 +18,3 @@ define(['Chance', 'mocha', 'chai', 'underscore'], function (Chance, mocha, chai, _) { | ||
describe("pick()", function () { | ||
it("returns a single element", function () { | ||
it("returns a single element when called without a count argument", function () { | ||
arr = ['a', 'b', 'c', 'd']; | ||
@@ -26,2 +26,18 @@ _(1000).times(function () { | ||
}); | ||
it("returns multiple elements when called with a count argument", function () { | ||
arr = ['a', 'b', 'c', 'd']; | ||
_(1000).times(function () { | ||
picked = chance.pick(arr, 3); | ||
expect(picked).to.have.length(3); | ||
}); | ||
}); | ||
it("doesn't destroy the original array when called with a count argument", function () { | ||
arr = ['a', 'b', 'c', 'd', 'e', 'f']; | ||
_(1000).times(function () { | ||
picked = chance.pick(arr, 3); | ||
expect(arr).to.have.length(6); | ||
}); | ||
}); | ||
}); | ||
@@ -34,2 +50,6 @@ | ||
expect(chance.shuffle(_.clone(arr))).to.have.length(5); | ||
expect(chance.shuffle(_.clone(arr))).to.contain('a'); | ||
var arr2 = _.clone(arr); | ||
chance.shuffle(arr2); | ||
expect(arr2).to.not.be.empty; | ||
}); | ||
@@ -36,0 +56,0 @@ }); |
@@ -76,3 +76,72 @@ define(['Chance', 'mocha', 'chai', 'underscore'], function (Chance, mocha, chai, _) { | ||
}); | ||
describe('color', function () { | ||
it("({format: 'hex'}) returns what looks a hex color", function () { | ||
_(1000).times(function () { | ||
var color = chance.color({format: 'hex'}); | ||
expect(color).to.be.a('string'); | ||
expect(color).to.have.length(7); | ||
expect(color).to.match(/#[a-z0-9]+/m); | ||
}); | ||
}); | ||
it("({format: 'hex', grayScale: true}) returns what looks a gray scale hex color", function () { | ||
_(1000).times(function () { | ||
var color = chance.color({format: 'hex', grayscale: true}); | ||
expect(color).to.be.a('string'); | ||
expect(color).to.have.length(7); | ||
expect(color).to.match(/#[a-z0-9]+/m); | ||
expect(color.slice(1, 3)).to.equal(color.slice(3, 5)); | ||
expect(color.slice(1, 3)).to.equal(color.slice(5, 7)); | ||
}); | ||
}); | ||
it("({format: 'shorthex'}) returns what looks a short hex color", function () { | ||
_(1000).times(function () { | ||
var color = chance.color({format: 'shorthex'}); | ||
expect(color).to.be.a('string'); | ||
expect(color).to.have.length(4); | ||
expect(color).to.match(/#[a-z0-9]+/m); | ||
}); | ||
}); | ||
it("({format: 'shorthex', grayScale: true}) returns what looks a gray scale short hex color", function () { | ||
_(1000).times(function () { | ||
var color = chance.color({format: 'shorthex', grayscale: true}); | ||
expect(color).to.be.a('string'); | ||
expect(color).to.have.length(4); | ||
expect(color).to.match(/#[a-z0-9]+/m); | ||
expect(color.slice(1, 2)).to.equal(color.slice(2, 3)); | ||
expect(color.slice(1, 2)).to.equal(color.slice(3, 4)); | ||
}); | ||
}); | ||
it("({format: 'rgb'}) returns what looks a rgb color", function () { | ||
_(1000).times(function () { | ||
var color = chance.color({format: 'rgb'}); | ||
expect(color).to.be.a('string'); | ||
var matchColors = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; | ||
var match = matchColors.exec(color); | ||
expect(match).to.have.length.of(4); | ||
expect(match[1]).to.be.within(0, 255); | ||
expect(match[2]).to.be.within(0, 255); | ||
expect(match[3]).to.be.within(0, 255); | ||
}); | ||
}); | ||
it("({format: 'rgb', grayScale: true}) returns what looks a gray scale rgb color", function () { | ||
_(1000).times(function () { | ||
var color = chance.color({format: 'rgb', grayscale: true}); | ||
expect(color).to.be.a('string'); | ||
var matchColors = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; | ||
var match = matchColors.exec(color); | ||
expect(match).to.have.length.of(4); | ||
expect(match[1]).to.be.within(0, 255); | ||
expect(match[1]).to.equal(match[2]); | ||
expect(match[1]).to.equal(match[3]); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2096
104
95398
18