SB-6.1-PRE

This commit is contained in:
ItzEmerald committed 2021-02-02 13:50:53 +00:00
1 parent 690169a409
commit 358a25f522
3760 files changed
+300059 -36

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
/**
* Phone number validator/formatter (UK numbers).
* Author: Brian Barnett, brian@3kb.co.uk, http://brianbar.net/ || http://3kb.co.uk/
* Date: 21/02/14
**/
!function(a){var b=["011# ### ####","01#1 ### ####","013873 #####","015242 #####","015394 #####","015395 #####","015396 #####","016973 #####","016974 #####","016977 ####","016977 #####","017683 #####","017684 #####","017687 #####","019467 #####","01### #####","01### ######","02# #### ####","03## ### ####","05### ######","0500 ######","07### ######","08## ### ###","08## ### ####","09## ### ####"],c=function(){var a=[];return b.forEach(function(b){var c="^"+b.split(" ").map(function(a){return a.split("").every(function(a){return"#"===a})?"\\d{"+a.length+"}":a.split("").map(function(a){return"#"===a?"\\d":a}).join("")}).join(" ")+"$";a.push({regex:new RegExp(c),mask:b})}),a};a._patterns=c(),a.isValid=function(a){return this._patterns.some(function(b){return b.regex.test(a)})},a.format=function(a,b){var c=this._patterns.map(function(a){return a});for(c.reverse(),b=void 0===b?" ":b;0!==c.length;){for(var d=c.pop(),e=a.replace(/[()\[\]\-_A-Za-z ]/gi,"").split(""),f=d.mask.split(""),g=0;g<f.length;g++)" "===f[g]&&e.splice(g,0," ");if(e=e.join(""),d.regex.test(e))return e.replace(/ /g,b)}return!1}}("undefined"==typeof exports?this.phoneNumber={}:exports);
+740
View File
@@ -0,0 +1,740 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
import phoneNumber from './helpers/phoneNumber.min.js'
const chance = new Chance()
// chance.address()
test('address() returns a string', t => {
t.true(_.isString(chance.address()))
})
test('address() starts with a number', t => {
_.times(1000, () => t.true(/[0-9]+.+/.test(chance.address())))
})
test('address() can take a short_suffix arg and obey it', t => {
_.times(1000, () => {
let address = chance.address({ short_suffix: true })
t.true(address.split(' ')[2].length < 5)
})
})
// chance.altitude()
test('altitude() looks right', t => {
t.is(typeof chance.altitude(), 'number')
})
test('altitude() is in the right range', t => {
_.times(1000, () => {
let altitude = chance.altitude()
t.true(altitude > 0)
t.true(altitude < 8848)
})
})
test('altitude() will accept a min and obey it', t => {
_.times(1000, () => {
let min = chance.floating({ min: 0, max: 8848 })
let altitude = chance.altitude({ min: min })
t.true(altitude > min)
t.true(altitude < 8848)
})
})
test('altitude() will accept a max and obey it', t => {
_.times(1000, () => {
let max = chance.floating({ min: 0, max: 8848 })
let altitude = chance.altitude({ max: max })
t.true(altitude > 0)
t.true(altitude < max)
})
})
// chance.areacode()
test('areacode() looks right', t => {
_.times(1000, () => {
let areacode = chance.areacode()
t.true(_.isString(areacode))
t.true(/^\(([2-9][0-8][0-9])\)$/.test(areacode))
})
})
test('areacode() can take parens', t => {
_.times(1000, () => {
let areacode = chance.areacode({ parens: false })
t.true(_.isString(areacode))
t.true(/^([2-9][0-8][0-9])$/.test(areacode))
})
})
// chance.city()
test('city() looks right', t => {
_.times(1000, () => {
let city = chance.city()
t.true(_.isString(city))
t.true(/[a-zA-Z]+/.test(city))
})
})
// chance.coordinates()
test('coordinates() looks right', t => {
_.times(1000, () => {
let coordinates = chance.coordinates()
t.true(_.isString(coordinates))
t.is(coordinates.split(',').length, 2)
})
})
test('coordinates() returns coordinates in DD format as default', t => {
_.times(1000, () => {
const CHARS_NOT_TO_CONTAIN = ['°', '’', '”']
let coordinates = chance.coordinates()
let [ latitude, longitude ] = coordinates.split(',')
t.true(_.isString(coordinates))
t.is(coordinates.split(',').length, 2)
t.true(CHARS_NOT_TO_CONTAIN.every(char => !latitude.includes(char)))
t.true(CHARS_NOT_TO_CONTAIN.every(char => !longitude.includes(char)))
})
})
test('coordinates() will obey DD format', t => {
_.times(1000, () => {
const CHARS_NOT_TO_CONTAIN = ['°', '’', '”']
let coordinates = chance.coordinates({format: 'dd'})
let [ latitude, longitude ] = coordinates.split(',')
t.true(_.isString(coordinates))
t.is(coordinates.split(',').length, 2)
t.true(CHARS_NOT_TO_CONTAIN.every(char => !latitude.includes(char)))
t.true(CHARS_NOT_TO_CONTAIN.every(char => !longitude.includes(char)))
})
})
test('coordinates() will obey DDM format', t => {
_.times(1000, () => {
const CHARS_TO_CONTAIN = ['°']
const CHARS_NOT_TO_CONTAIN = ['’', '”']
let coordinates = chance.coordinates({format: 'ddm'})
let [ latitude, longitude ] = coordinates.split(',')
t.true(_.isString(coordinates))
t.is(coordinates.split(',').length, 2)
t.true(CHARS_TO_CONTAIN.every(char => latitude.includes(char)))
t.true(CHARS_TO_CONTAIN.every(char => longitude.includes(char)))
t.true(CHARS_NOT_TO_CONTAIN.every(char => !latitude.includes(char)))
t.true(CHARS_NOT_TO_CONTAIN.every(char => !longitude.includes(char)))
})
})
test('coordinates() will obey DMS format', t => {
_.times(1000, () => {
const CHARS_TO_CONTAIN = ['°', '’', '”']
let coordinates = chance.coordinates({format: 'dms'})
let [ latitude, longitude ] = coordinates.split(',')
t.true(_.isString(coordinates))
t.is(coordinates.split(',').length, 2)
t.true(CHARS_TO_CONTAIN.every(char => latitude.includes(char)))
t.true(CHARS_TO_CONTAIN.every(char => longitude.includes(char)))
})
})
// chance.counties()
test('counties() returns an array of counties', t => {
t.true(_.isArray(chance.counties()))
})
test('counties() returns a (long) county name', t => {
_.times(1000, () => t.true(chance.counties({ full: true }).length > 2))
})
test('counties() can return a random (long) county name', t => {
_.times(1000, () => {
t.true(chance.counties({ full: true, country: 'uk' }).length > 2)
})
})
// chance.countries()
test('countries() returns an array of countries', t => {
t.true(_.isArray(chance.countries()))
})
// chance.country()
test('country() returns a random (short) country name', t => {
_.times(1000, () => {
t.is(chance.country().length, 2)
})
})
test('country() returns a random (long) country name', t => {
_.times(1000, () => {
t.true(chance.country({ full: true }).length > 2)
})
})
// chance.county()
test('county() returns a random county name', t => {
_.times(1000, () => {
t.true(_.isString(chance.county()))
})
})
test('country() returns a random (long) country name', t => {
_.times(1000, () => {
t.true(chance.country({ full: true }).length > 2)
})
})
// chance.depth()
test('depth() looks right', t => {
t.is(typeof chance.depth(), 'number')
})
test('depth() is in the right range', t => {
_.times(1000, () => {
let depth = chance.depth()
t.true(depth > -10994)
t.true(depth < 0)
})
})
test('depth() will accept a min and obey it', t => {
_.times(1000, () => {
let min = chance.floating({ min: -10994, max: 0 })
let depth = chance.depth({ min: min })
t.true(depth > min)
t.true(depth < 0)
})
})
test('depth() will accept a max and obey it', t => {
_.times(1000, () => {
let max = chance.floating({ min: -10994, max: 0 })
let depth = chance.depth({ max: max })
t.true(depth > -10994)
t.true(depth < max)
})
})
// chance.geohash
test('geohash() looks right', t => {
let geohash = chance.geohash()
t.true(_.isString(geohash))
t.is(geohash.length, 7)
})
test('geohash() will accept a length and obey it', t => {
_.times(1000, () => {
let length = chance.d10()
let geohash = chance.geohash({ length: length })
t.is(geohash.length, length)
})
})
// chance.latitude()
test('latitude() looks right', t => {
t.is(typeof chance.latitude(), 'number')
})
test('latitude() is in the right range', t => {
_.times(1000, () => {
let latitude = chance.latitude()
t.true(latitude >= -90)
t.true(latitude <= 90)
})
})
test('latitude() will accept a min and obey it', t => {
_.times(1000, () => {
let min = chance.floating({ min: -90, max: 90 })
let latitude = chance.latitude({ min: min })
t.true(latitude >= min)
t.true(latitude <= 90)
})
})
test('latitude() will accept a max and obey it', t => {
_.times(1000, () => {
let max = chance.floating({ min: -90, max: 90 })
let latitude = chance.latitude({ max: max })
t.true(latitude >= -90)
t.true(latitude <= max)
})
})
test('latitude() returns latitude in DD format as default', t => {
_.times(1000, () => {
const CHARS_NOT_TO_CONTAIN = ['°', '’', '”']
let latitude = chance.latitude()
t.is(typeof latitude, 'number')
t.true(CHARS_NOT_TO_CONTAIN.every(char => !latitude.toString().includes(char)))
})
})
test('latitude() will obey DD format', t => {
_.times(1000, () => {
const CHARS_NOT_TO_CONTAIN = ['°', '’', '”']
let latitude = chance.latitude({format: 'dd'})
t.is(typeof latitude, 'number')
t.true(CHARS_NOT_TO_CONTAIN.every(char => !latitude.toString().includes(char)))
})
})
test('latitude() will obey DDM format', t => {
_.times(1000, () => {
const CHARS_TO_CONTAIN = ['°']
const CHARS_NOT_TO_CONTAIN = ['’', '”']
let latitude = chance.latitude({format: 'ddm'})
t.true(_.isString(latitude))
t.true(CHARS_TO_CONTAIN.every(char => latitude.includes(char)))
t.true(CHARS_NOT_TO_CONTAIN.every(char => !latitude.includes(char)))
})
})
test('latitude() will obey DMS format', t => {
_.times(1000, () => {
const CHARS_TO_CONTAIN = ['°', '’', '”']
let latitude = chance.latitude({format: 'dms'})
t.true(_.isString(latitude))
t.true(CHARS_TO_CONTAIN.every(char => latitude.includes(char)))
})
})
// chance.longitude()
test('longitude() looks right', t => {
t.is(typeof chance.longitude(), 'number')
})
test('longitude() is in the right range', t => {
_.times(1000, () => {
let longitude = chance.longitude()
t.true(longitude >= -180)
t.true(longitude <= 180)
})
})
test('longitude() will accept a min and obey it', t => {
_.times(1000, () => {
let min = chance.floating({ min: -180, max: 180 })
let longitude = chance.longitude({ min: min })
t.true(longitude >= min)
t.true(longitude <= 180)
})
})
test('longitude() will accept a max and obey it', t => {
_.times(1000, () => {
let max = chance.floating({ min: -180, max: 180 })
let longitude = chance.longitude({ max: max })
t.true(longitude >= -180)
t.true(longitude <= max)
})
})
test('longitude() returns longitude in DD format as default', t => {
_.times(1000, () => {
const CHARS_NOT_TO_CONTAIN = ['°', '’', '”']
let longitude = chance.longitude()
t.is(typeof longitude, 'number')
t.true(CHARS_NOT_TO_CONTAIN.every(char => !longitude.toString().includes(char)))
})
})
test('longitude() will obey DD format', t => {
_.times(1000, () => {
const CHARS_NOT_TO_CONTAIN = ['°', '’', '”']
let longitude = chance.longitude({format: 'dd'})
t.is(typeof longitude, 'number')
t.true(CHARS_NOT_TO_CONTAIN.every(char => !longitude.toString().includes(char)))
})
})
test('longitude() will obey DDM format', t => {
_.times(1000, () => {
const CHARS_TO_CONTAIN = ['°']
const CHARS_NOT_TO_CONTAIN = ['’', '”']
let longitude = chance.longitude({format: 'ddm'})
t.true(_.isString(longitude))
t.true(CHARS_TO_CONTAIN.every(char => longitude.includes(char)))
t.true(CHARS_NOT_TO_CONTAIN.every(char => !longitude.includes(char)))
})
})
test('longitude() will obey DMS format', t => {
_.times(1000, () => {
const CHARS_TO_CONTAIN = ['°', '’', '”']
let longitude = chance.longitude({format: 'dms'})
t.true(_.isString(longitude))
t.true(CHARS_TO_CONTAIN.every(char => longitude.includes(char)))
})
})
// chance.phone()
test('phone() returns a string', t => {
t.true(_.isString(chance.phone()))
})
test('phone() looks like an actual phone number', t => {
t.true(/^\(([2-9][0-8][0-9])\)?[\-. ]?([2-9][0-9]{2,2})[\-. ]?([0-9]{4,4})$/.test(chance.phone()))
})
test('phone() obeys formatted option', t => {
_.times(1000, () => {
let phone = chance.phone({ formatted: false })
t.true(_.isString(phone))
t.true(/^[2-9][0-8]\d[2-9]\d{6,6}$/.test(phone))
})
})
test('phone() obeys formatted option and parens option', t => {
_.times(1000, () => {
let phone = chance.phone({ formatted: false, parens: true })
t.true(_.isString(phone))
t.true(/^[2-9][0-8]\d[2-9]\d{6,6}$/.test(phone))
})
})
test('phone() with uk option works', t => {
t.true(_.isString(chance.phone({ country: 'uk' })))
})
test('phone() with uk option works and mobile option', t => {
t.true(_.isString(chance.phone({ country: 'uk', mobile: true })))
})
test('phone() with uk country looks right', t => {
t.true(phoneNumber.isValid(chance.phone({ country: 'uk' })))
})
test('phone() with uk country unformatted looks right', t => {
t.true(phoneNumber.isValid(phoneNumber.format(chance.phone({
country: 'uk',
formatted: false
}))))
})
test('phone() with uk country and mobile option looks right', t => {
_.times(1000, () => {
t.true(phoneNumber.isValid(chance.phone({
country: 'uk',
mobile: true
})))
})
})
test('phone() with uk country and mobile option unformatted looks right', t => {
_.times(1000, () => {
t.true(phoneNumber.isValid(phoneNumber.format(chance.phone({
country: 'uk',
mobile: true,
formatted: false
}))))
})
})
test('phone() with fr country works', t => {
t.true(_.isString(chance.phone({ country: 'fr' })))
})
test('phone() with fr country works with mobile option', t => {
t.true(_.isString(chance.phone({ country: 'fr', mobile: true })))
})
test('phone() with fr country looks right', t => {
_.times(1000, () => {
t.true(/0[123459] .. .. .. ../.test(chance.phone({ country: 'fr' })))
})
})
test('phone() with fr country looks right unformatted', t => {
_.times(1000, () => {
t.true(/0........./.test(chance.phone({
country: 'fr',
formatted: false
})))
})
})
test('phone() with fr country on mobile looks right', t => {
_.times(1000, () => {
t.true(/0[67] .. .. .. ../.test(chance.phone({
country: 'fr',
mobile: true
})))
})
})
test('phone() with fr country on mobile, unformatted looks right', t => {
_.times(1000, () => {
t.true(/0[67]......../.test(chance.phone({
country: 'fr',
mobile: true,
formatted: false
})))
})
})
test('phone() with br country option works', t => {
t.true(_.isString(chance.phone({ country: 'br' })))
})
test('phone() with br country and mobile option works', t => {
t.true(_.isString(chance.phone({ country: 'br', mobile: true })))
})
test('phone() with br country and formatted false option return a correct format', t => {
t.true(/([0-9]{2})([2-5]{1})([0-9]{3})([0-9]{4})/.test(chance.phone({
country: 'br',
mobile: false,
formatted: false
})))
})
test('phone() with br country, formatted false and mobile option return a correct format', t => {
t.true(/([0-9]{2})\9([0-9]{4})([0-9]{4})/.test(chance.phone({
country: 'br',
mobile: true,
formatted: false
})))
})
test('phone() with br country and formatted option apply the correct mask', t => {
t.true(/\(([0-9]{2})\) ([2-5]{1})([0-9]{3})\-([0-9]{4})/.test(chance.phone({
country: 'br',
mobile: false,
formatted: true
})))
})
test('phone() with br country, formatted and mobile option apply the correct mask', t => {
t.true(/\(([0-9]{2})\) 9([0-9]{4})\-([0-9]{4})/.test(chance.phone({
country: 'br',
mobile: true,
formatted: true
})))
})
// chance.postal()
test('postal() returns a valid basic postal code', t => {
_.times(1000, () => {
let postal = chance.postal()
t.is(postal.length, 7)
postal.split('').map((char) => {
t.is(char.toUpperCase(), char)
})
})
})
test('postcode() returns a valid basic postcode', t => {
_.times(10, () => {
let postcode = chance.postcode();
t.regex(postcode, /^[A-Z]{1,2}\d[A-Z\d]? \d[A-Z]{2}$/);
})
})
// chance.province()
test('province() returns a random (short) province name', t => {
_.times(1000, () => t.true(chance.province().length < 3))
})
test('province() can return a long random province name', t => {
_.times(1000, () => t.true(chance.province({ full: true }).length > 2))
})
test('province() can return a random long "it" province', t => {
_.times(1000, () => {
t.true(chance.province({country: 'it', full: true }).length > 2)
})
})
// chance.provinces()
test('provinces() returns an array of provinces', t => {
t.true(_.isArray(chance.provinces()))
})
test('provinces() supports internationalization', t => {
t.not(chance.provinces(), chance.provinces({ country: 'it' }))
})
// chance.state()
test('state() returns a random (short) state name', t => {
_.times(1000, () => t.true(chance.state().length < 3))
})
test('state() can take a country and return a state', t => {
_.times(1000, () => t.true(chance.state({ country: 'it' }).length === 3))
})
test('state() can return full state name', t => {
_.times(1000, () => {
t.true(chance.state({
full: true
}).length > 2)
})
})
test('state() with country returns a long state name', t => {
_.times(1000, () => {
t.true(chance.state({
country: 'it',
full: true
}).length > 2)
})
_.times(1000, () => {
t.true(chance.state({
country: 'uk',
full: true
}).length > 2)
})
})
// chance.states()
test('states() returns an array of states', t => {
t.true(_.isArray(chance.states()))
})
test('states() returns all 50 states and DC', t => {
t.is(chance.states().length, 51)
})
test('states() with territories returns 50 US states, DC, and 7 US territories', t => {
t.is(chance.states({
territories: true
}).length, 58)
})
test('states() without us states and dc returns 7 US territories', t => {
t.is(chance.states({
territories: true,
us_states_and_dc: false
}).length, 7)
})
test('states() with armed forces returns 50 states, DC, and 3 armed forces military states', t => {
t.is(chance.states({
armed_forces: true
}).length, 54)
})
test('states() with armed forces without states returns 3 armed forces states', t => {
t.is(chance.states({
armed_forces: true,
us_states_and_dc: false
}).length, 3)
})
test('states() with all options returns 61 items', t => {
t.is(chance.states({
territories: true,
armed_forces: true
}).length, 61)
})
test('states() without states returns 7 territories and 3 armed forces states', t => {
t.is(chance.states({
territories: true,
armed_forces: true,
us_states_and_dc: false
}).length, 10)
})
test('states() with country of "it" returns 20 regions', t => {
t.is(chance.states({
country: 'it'
}).length, 20)
})
test('states() with country of "uk" returns 129 UK counties', t => {
t.is(chance.states({
country: 'uk'
}).length, 129)
})
test('states() with country of "mx" returns 32 MX states', t => {
t.is(chance.states({
country: 'mx'
}).length, 32)
})
// chance.street()
test('street() works', t => {
_.times(100, () => t.is(typeof chance.street(), 'string'))
})
test('street() works with it country', t => {
_.times(100, () => t.is(typeof chance.street({ country: 'it' }), 'string'))
})
// chance.street_suffix()
test('street_suffix() returns a single suffix', t => {
_.times(1000, () => {
let suffix = chance.street_suffix()
t.is(typeof suffix, 'object')
t.is(typeof suffix.name, 'string')
t.is(typeof suffix.abbreviation, 'string')
})
})
// chance.street_suffixes()
test('street_suffixes() returns the suffix array', t => {
let suffixes = chance.street_suffixes()
t.true(_.isArray(suffixes))
suffixes.map((suffix) => {
t.truthy(suffix.name)
t.truthy(suffix.abbreviation)
})
})
test('street_suffixes() are short', t => {
let suffixes = chance.street_suffixes()
suffixes.map((suffix) => {
t.true(suffix.abbreviation.length < 5)
})
})
test('street_suffixes() are longish', t => {
let suffixes = chance.street_suffixes()
suffixes.map((suffix) => {
t.true(suffix.name.length > 2)
})
})
// chance.zip()
test('zip() returns a valid basic zip code', t => {
_.times(1000, () => {
let zip = chance.zip()
t.is(zip.length, 5)
t.true(/(^\d{5}$)|(^\d{5}-\d{4}$)/.test(zip))
})
})
test('zip() returns a valid zip+4 code', t => {
_.times(1000, () => {
let zip = chance.zip({ plusfour: true })
t.is(zip.length, 10)
t.true(/(^\d{5}$)|(^\d{5}-\d{4}$)/.test(zip))
})
})
+40
View File
@@ -0,0 +1,40 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
const timeout = (seconds) => {
new Promise((resolve, reject) => {
setTimeout(() => resolve(), seconds)
})
}
//chance.animal()
test('returns an animal', t => {
_.times(1000, () => {
let animal = chance.animal({
type: "desert"
})
t.true(_.isString(animal))
t.true(animal.length >= 2)
})
})
test('returns an animal even if type is not specified', t => {
_.times(1000, () => {
let animal = chance.animal()
t.true(_.isString(animal))
t.true(animal.length >= 2)
})
})
test('throws an error if the type is not part of the animals object', t => {
_.times(1000, () => {
const fn = () => chance.animal({
type: "banana"
})
t.throws(fn, "Please pick from desert, ocean, grassland, forest, zoo, pets, farm.")
})
})
+560
View File
@@ -0,0 +1,560 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
const timeout = (seconds) => {
new Promise((resolve, reject) => {
setTimeout(() => resolve(), seconds)
})
}
test('bool() returns a random boolean', t => {
let bool = chance.bool()
t.is(typeof bool, 'boolean')
})
test('bool() is within the bounds of what we would call random', t => {
let trueCount = 0;
_.times(1000, () => {
if (chance.bool()) {
trueCount++
}
})
// The probability of this test failing is approximately 4.09e-86.
// So, in theory, it could give a false negative, but the sun will
// probably die long before that happens.
t.true((trueCount > 200) && (trueCount < 800))
})
test('bool() takes and obeys likelihood', t => {
let trueCount = 0
_.times(1000, () => {
if (chance.bool({ likelihood: 30 })) {
trueCount++
}
})
// Expect it to average around 300
t.true((trueCount > 200) && (trueCount < 400))
trueCount = 0
_.times(1000, () => {
if (chance.bool({ likelihood: 99 })) {
trueCount++
}
})
// Expect it to average at 990
t.true(trueCount > 900)
})
test('bool() throws an error if likelihood < 0 or > 100', t => {
const fn1 = () => chance.bool({likelihood: -23})
t.throws(fn1, RangeError)
const fn2 = () => chance.bool({likelihood: 7933})
t.throws(fn2, RangeError)
})
test('Chance() null works', async t => {
t.plan(1)
let chance1 = Chance(null)
// Wait 5 ms before creating chance2 else sometimes they happen on the same
// tick and end up with the same seed!
await timeout(5)
let chance2 = Chance(null)
t.not(chance1.random(), chance2.random())
})
test('Chance() does return differing results if differing seeds provided', t => {
let chance1 = new Chance(12345)
let chance2 = new Chance(54321)
t.not(chance1.random(), chance2.random())
})
test('Chance() does not return repeatable results if no seed provided', async t => {
t.plan(1000)
let chance1 = new Chance()
await timeout(5)
let chance2 = new Chance()
_.times(1000, () => {
t.not(chance1.random(), chance2.random())
})
})
test('Chance() returns repeatable results if seed provided on the Chance object', t => {
let seed = new Date().getTime()
let chance1 = new Chance(seed)
let chance2 = new Chance(seed)
_.times(1000, () => {
t.is(chance1.random(), chance2.random())
})
})
test('Chance() returns repeatable results if a string is provided as a seed', t => {
let seed = "foo"
let chance1 = new Chance(seed)
let chance2 = new Chance(seed)
_.times(1000, () => {
t.is(chance1.random(), chance2.random())
})
})
test('Chance() returns different results if two different strings are provided', t => {
let chance1 = new Chance("foo")
let chance2 = new Chance("baz")
_.times(1000, () => {
t.not(chance1.random(), chance2.random())
})
})
test('Chance() returns different results if two different strings are provided redux', t => {
// Credit to @dan-tilley for noticing this flaw in the old seed
let chance1 = new Chance("abe")
let chance2 = new Chance("acc")
_.times(1000, () => {
t.not(chance1.random(), chance2.random())
})
})
test('Chance() returns different results if multiple arguments are provided', t => {
let seed = new Date().getTime()
let chance1 = new Chance(seed, "foo")
let chance2 = new Chance(seed, "bar")
_.times(1000, () => {
t.not(chance1.random(), chance2.random())
})
})
test('Chance() will take an arbitrary function for the seed and use it', t => {
let chance = new Chance(() => 123)
_.times(1000, () => {
t.is(chance.random(), 123)
})
})
test('character() returns a character', t => {
let char = chance.character()
t.is(typeof char, 'string')
t.is(char.length, 1)
})
test('character() pulls only from pool, when specified', t => {
_.times(1000, () => {
let char = chance.character({ pool: 'abcde' })
t.true(/[abcde]/.test(char))
})
})
test('character() allows only alpha', t => {
_.times(1000, () => {
let char = chance.character({ alpha: true })
t.true(/[a-zA-Z]/.test(char))
})
})
test('character() allows only alphanumeric', t => {
_.times(1000, () => {
let char = chance.character({ alpha: true, numeric: true })
t.true(/[a-zA-Z0-9]/.test(char))
})
})
test('character() obeys upper case', t => {
_.times(1000, () => {
let char = chance.character({ alpha: true, casing: 'upper' })
t.true(/[A-Z]/.test(char))
})
})
test('character() obeys lower case', t => {
_.times(1000, () => {
let char = chance.character({ alpha: true, casing: 'lower' })
t.true(/[a-z]/.test(char))
})
})
test('floating() returns a random floating', t => {
t.is(typeof chance.floating(), 'number')
})
test('floating() can take both a max and min and obey them both', t => {
_.times(1000, () => {
let floating = chance.floating({ min: 90, max: 100 })
t.true(floating > 89)
t.true(floating < 101)
})
})
test('floating() will not take fixed + min that would be out of range', t => {
const fn = () => chance.floating({ fixed: 13, min: -9007199254740992 })
t.throws(fn, "Chance: Min specified is out of range with fixed. Min should be, at least, -900.7199254740992")
})
test('floating() will not take fixed + max that would be out of range', t => {
const fn = () => chance.floating({ fixed: 13, max: 9007199254740992 })
t.throws(fn, "Chance: Max specified is out of range with fixed. Max should be, at most, 900.7199254740992")
})
test('floating() obeys the fixed parameter, when present', t => {
_.times(1000, () => {
let floating = chance.floating({ fixed: 4 })
let decimals = floating.toString().split('.')[1] ? floating.toString().split('.')[1] : ''
t.true(decimals.length < 5)
})
})
test('floating() can take fixed and obey it', t => {
_.times(1000, () => {
let floating = chance.floating({ fixed: 3 })
let parsed = parseFloat(floating.toFixed(3))
t.is(floating, parsed)
})
})
test('floating() will not take both fixed and precision', t => {
const fn = () => chance.floating({fixed: 2, precision: 8})
t.throws(fn, 'Chance: Cannot specify both fixed and precision.')
})
test('get() works as expected', t => {
let data = chance.get('lastNames')
t.true(typeof data === 'object')
})
test('hex() works as expected', t => {
_.times(1000, () => {
t.true(/[0-9a-f]/.test(chance.hex()))
})
})
test('hex() can take Upper and obey it', t => {
_.times(1000, () => {
t.true(/[0-9A-F]/.test(chance.hex({ casing: 'upper' })))
})
})
test('integer() returns a random integer', t => {
t.is(typeof chance.integer(), 'number')
})
test('integer() is sometimes negative, sometimes positive', t => {
let positiveCount = 0
_.times(1000, () => {
if (chance.integer() > 0) {
positiveCount++
}
})
// Note: In very extreme circumstances this test may fail as, by its
// nature it's random. But it's a low enough percentage that I'm
// willing to accept it.
t.true((positiveCount > 200) && (positiveCount < 800))
})
test('integer() can take a zero min and obey it', t => {
_.times(1000, () => {
t.true(chance.integer({ min: 0 }) > 0)
})
})
test('integer() can take a negative min and obey it', t => {
_.times(1000, () => {
t.true(chance.integer({ min: -25 }) > -26)
})
})
test('integer() can take a negative min and max and obey both', t => {
_.times(1000, () => {
let integer = chance.integer({ min: -25, max: -1 })
t.true((integer > -26) && integer < 0)
})
})
test('integer() can take a min with absolute value less than max and return in range above', t => {
let count = 0
_.times(1000, () => {
// With a range this large we'd expect most values to be
// greater than 1 if this works correctly.
if (Math.abs(chance.integer({ min: -1, max: 1000000 })) < 2) {
count++
}
})
t.true(count < 900)
})
test('integer() throws an error when min > max', t => {
const fn = () => chance.integer({ min: 1000, max: 500 })
t.throws(fn, 'Chance: Min cannot be greater than Max.')
})
test('letter() returns a letter', t => {
_.times(1000, () => {
let letter = chance.letter()
t.is(typeof letter, 'string')
t.is(letter.length, 1)
t.true(letter.match(/[a-z]/) !== null)
})
})
test('letter() can take upper case', t => {
_.times(1000, () => {
let letter = chance.letter({ casing: 'upper' })
t.is(typeof letter, 'string')
t.is(letter.length, 1)
t.true(letter.match(/[A-Z]/) !== null)
})
})
test('natural() returns a random natural', t => {
t.is(typeof chance.natural(), 'number')
})
test('natural() throws an error if min < 0', t => {
const fn = () => chance.natural({ min: -23 })
t.throws(fn, 'Chance: Min cannot be less than zero.')
})
test('natural() is always positive or zero', t => {
let positiveCount = 0
_.times(1000, () => {
if (chance.natural() >= 0) {
positiveCount++
}
})
t.is(positiveCount, 1000)
})
test('natural() can take just a min and obey it', t => {
_.times(1000, () => {
t.true(chance.natural({ min: 9007199254740991 }) > 9007199254740990)
})
})
test('natural() can take just a max and obey it', t => {
_.times(1000, () => {
t.true(chance.natural({ max: 100 }) < 101)
})
})
test('natural() can take both a max and min and obey them both', t => {
_.times(1000, () => {
let natural = chance.natural({ min: 90, max: 100 })
t.true(natural > 89)
t.true(natural < 101)
})
})
test('natural() works with both bounds 0', t => {
_.times(1000, () => {
t.is(chance.natural({ min: 0, max: 0 }), 0)
})
})
test('natural() respects numerals', t => {
_.times(1000, () => {
let natural = chance.natural({ numerals: 2 })
t.true(natural <= 99)
t.true(natural >= 10)
})
})
test('natural() works with excluded numbers', t => {
_.times(1000, () => {
let natural = chance.natural({ min: 1, max: 5, exclude: [1, 3] })
t.true(natural <= 5)
t.true(natural >= 1)
t.true(natural !== 1)
t.true(natural !== 3)
})
})
test('natural() works within empty exclude option', t => {
_.times(1000, () => {
let natural = chance.natural({ min: 1, max: 5, exclude: [] })
t.true(natural <= 5)
t.true(natural >= 1)
})
})
test('natural() throws an error if exclude is not an array', t => {
const fn = () => chance.natural({ min: 1, max: 5, exclude: "foo" })
t.throws(fn, 'Chance: exclude must be an array.')
})
test('natural() throws an error if exclude is not an array', t => {
const fn = () => chance.natural({ min: 1, max: 5, exclude: ["puppies", 1] })
t.throws(fn, 'Chance: exclude must be numbers.')
})
test('natural() throws an error if min > max', t => {
const fn = () => chance.natural({ min: 1000, max: 500 })
t.throws(fn, 'Chance: Min cannot be greater than Max.')
})
test('natural() throws an error if numerals is less than 1', t => {
const fn = () => chance.natural({ numerals: 0 })
t.throws(fn, 'Chance: Numerals cannot be less than one.')
})
test('prime() returns a number', t => {
t.is(typeof chance.prime(), 'number')
})
test('prime() throws an error if min < 0', t => {
const fn = () => chance.prime({ min: -23 })
t.throws(fn, 'Chance: Min cannot be less than zero.')
})
test('prime() throws an error if min > max', t => {
const fn = () => chance.prime({ min: 1000, max: 500 })
t.throws(fn, 'Chance: Min cannot be greater than Max.')
})
test('prime() is always positive and odd (or 2)', t => {
let positiveCount = 0
_.times(1000, () => {
const prime = chance.prime()
if (prime > 0 && (prime % 2 === 1 || prime === 2)) {
positiveCount++
}
})
t.is(positiveCount, 1000)
})
test('prime() can take just a min and obey it', t => {
_.times(1000, () => {
t.true(chance.prime({ min: 5000 }) >= 5000)
})
})
test('prime() can take just a max and obey it', t => {
_.times(1000, () => {
t.true(chance.prime({ max: 20000 }) <= 20000)
})
})
test('prime() can take both a max and min and obey them both', t => {
_.times(1000, () => {
const prime = chance.prime({ min: 90, max: 100 })
t.true(prime >= 90)
t.true(prime <= 100)
})
})
test('set() works as expected', t => {
let cData = { lastNames: ['customName', 'testLast'] }
chance.set(cData)
let data = chance.get('lastNames')
t.true(_.isArray(data))
t.is(data.length, 2)
})
test('string() returns a string', t => {
t.is(typeof chance.string(), 'string')
})
test('string() obeys length, when specified', t => {
_.times(1000, () => {
let length = chance.natural({ min: 1, max: 25 })
t.is(chance.string({ length: length }).length, length)
})
})
test('string() throws error if length < 0', t => {
const fn = () => chance.string({ length: -23 })
t.throws(fn, 'Chance: Length cannot be less than zero.')
})
test('string() returns only letters with alpha', t => {
_.times(1000, () => {
let str = chance.string({ alpha: true })
t.true(/[a-zA-Z]+/.test(str))
})
})
test('string() obeys upper case', t => {
_.times(1000, () => {
let str = chance.string({ alpha: true, casing: 'upper' })
t.true(/[A-Z]+/.test(str))
})
})
test('string() obeys lower case', t => {
_.times(1000, () => {
let str = chance.string({ alpha: true, casing: 'lower' })
t.true(/[a-z]+/.test(str))
})
})
test('string() obeys symbol', t => {
_.times(1000, () => {
let str = chance.string({ symbols: true })
t.true(/[\!\@\#\$\%\^\&\*\(\)\[\]]+/.test(str))
})
})
test('string() can take just a min and obey it', t => {
_.times(1000, () => {
t.true(chance.string({ min: 6 }).length >= 6)
})
})
test('string() can take just a max and obey it', t => {
_.times(1000, () => {
t.true(chance.string({ max: 20 }).length <= 20)
})
})
test('falsy() should return a falsy value', t => {
_.times(1000, () => {
const value = chance.falsy()
t.falsy(value)
})
})
test('falsy() should return a falsy value using a pool data', t => {
_.times(1000, () => {
const value = chance.falsy({pool: [null, undefined]})
t.falsy(value)
})
})
test('template() returns alpha numeric substituted', t => {
_.times(1000, () => {
let str = chance.template('ID-{Aa}-{##}')
t.regex(str, /^ID-[A-Z][a-z]-[0-9][0-9]$/)
})
})
test('template() rejects unknown tokens', t => {
t.throws(() => chance.template('{Aa-}'), 'Invalid replacement character: "-".')
t.throws(() => chance.template('{Aa{}'), 'Invalid replacement character: "{".')
t.throws(() => chance.template('{Aab}'), 'Invalid replacement character: "b".')
})
test('template() allows escape sequnce', t => {
t.is(chance.template('\\\\ID-\\{Aa\\}'), '\\ID-{Aa}')
})
test('template() rejects invalid escape sequnce', t => {
t.throws(() => chance.template('ID-\\Aa'), 'Invalid escape sequence: "\\A".')
})
test('template() cannot be undefined', t => {
t.throws(() => chance.template(), 'Template string is required')
})
test('template() cannot be empty', t => {
t.throws(() => chance.template(''), 'Template string is required')
})
+31
View File
@@ -0,0 +1,31 @@
import test from "ava";
import Chance from "../chance.js";
import _ from "lodash";
const chance = new Chance();
// chance.buffer()
test("buffer() returns a random buffer", t => {
_.times(1000, () => {
let buffer = chance.buffer();
t.true(_.isBuffer(buffer));
let len = buffer.byteLength;
t.true(len >= 5);
t.true(len <= 20);
});
});
// chance.buffer()
test("buffer() will obey bounds", t => {
_.times(1000, () => {
let buffer = chance.buffer({ length: 12 });
t.true(_.isBuffer(buffer));
t.is(buffer.byteLength, 12);
});
});
// chance.buffer()
test("buffer() throws if length < 0", t => {
const fn = () => chance.buffer({ length: -3 });
t.throws(fn, "Chance: Length cannot be less than zero.");
});
+15
View File
@@ -0,0 +1,15 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
test('cnpj() returns a random valid taxpayer number for Brazil companies (CNPJ)', t => {
_.times(1000, () => {
let cnpj = chance.cnpj()
t.true(_.isString(cnpj))
t.true(/^\d{2}.\d{3}.\d{3}\/\d{4}-\d{2}$/m.test(cnpj))
t.is(cnpj.length, 18)
})
})
+116
View File
@@ -0,0 +1,116 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
const fileExtensions = {
"raster": [ "bmp", "gif", "gpl", "ico", "jpeg", "psd", "png", "psp", "raw",
"tiff" ],
"vector": [ "3dv", "amf", "awg", "ai", "cgm", "cdr", "cmx", "dxf", "e2d",
"egt", "eps", "fs", "odg", "svg", "xar" ],
"3d": [ "3dmf", "3dm", "3mf", "3ds", "an8", "aoi", "blend", "cal3d", "cob",
"ctm", "iob", "jas", "max", "mb", "mdx", "obj", "x", "x3d" ],
"document": [ "doc", "docx", "dot", "html", "xml", "odt", "odm", "ott", "csv",
"rtf", "tex", "xhtml", "xps" ]
}
// chance.file()
test('file() returns random file length with random extension', t => {
_.times(1000, () => {
let file = chance.file()
t.true(_.isString(file))
t.is(file.split('.').length, 2)
})
})
test('file() returns error if wrong fileType provided', t => {
_.times(1000, () => {
const fn = () => chance.file({ fileType: 'not_specified' })
t.throws(fn, 'Chance: Expect file type value to be \'raster\', \'vector\', \'3d\' or \'document\'')
})
})
test('file() does not return error if legit fileType provided', t => {
_.times(1000, () => {
const fn = () => chance.file({ fileType: 'raster' })
t.notThrows(fn)
})
})
test('file() returns filename with specific extension type', t => {
_.times(1000, () => {
let file = chance.file({ fileType: 'raster' })
t.true(_.isString(file))
let extension = file.split('.')[1]
t.true(fileExtensions['raster'].indexOf(extension) !== -1)
})
})
test('file() returns filename with specific extension', t => {
_.times(1000, () => {
let file = chance.file({ extension: 'doc' })
let extension = file.split('.')[1]
t.is(extension, 'doc')
})
})
test('file() can take a length and obey it', t => {
_.times(1000, () => {
let length = chance.d10()
let file = chance.file({ length: length })
let filename = file.split('.')[0]
t.is(filename.length, length)
})
})
test('file() can take a pool of extensions and obey them', t => {
_.times(1000, () => {
let extensions = [ 'bmp', '3dv', '3dmf', 'doc' ]
let file = chance.file({ extensions: extensions })
let extension = file.split('.')[1]
t.true(extensions.indexOf(extension) !== -1)
})
})
test('file() can take pool of extensions by object collection and obey them', t => {
const objectExtensionCollection = {
"one": [ "extension_one_1", "extension_one_2", "extension_one_3" ],
"two": [ "extension_two_1", "extension_two_2", "extension_two_3" ],
"three": [ "extension_three_1", "extension_three_2", "extension_three_3" ]
}
_.times(1000, () => {
let file = chance.file({ extensions: objectExtensionCollection })
let extension = file.split('.')[1]
let extensionCount = 0
for (let key in objectExtensionCollection) {
let collection = objectExtensionCollection[key]
collection.map((ext) => {
if (ext === extension) {
extensionCount++
}
})
}
t.is(extensionCount, 1)
})
})
test('file() throws if bad extensions option provided', t => {
const fn = () => chance.file({ extensions: 10 })
t.throws(fn, 'Chance: Extensions must be an Array or Object')
})
test('file() does not throw if good extensions option provided as array', t => {
_.times(1000, () => {
const fn = () => chance.file({ extensions: fileExtensions.document })
t.notThrows(fn)
})
})
test('file() does not throw if good extensions option provided as object', t => {
_.times(1000, () => {
const fn = () => chance.file({ extensions: fileExtensions })
t.notThrows(fn)
})
})
+220
View File
@@ -0,0 +1,220 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.cc()
test('cc() passes the luhn algorithm', t => {
_.times(1000, () => {
let number = chance.cc()
t.true(chance.luhn_check(number))
})
})
test('cc() can take a type arg and obey it', t => {
_.times(1000, () => {
let type = chance.cc_type({ raw: true })
let number = chance.cc({ type: type.name })
t.is(number.length, type.length)
})
})
test('cc() can take a short_name type arg and obey it', t => {
_.times(1000, () => {
let type = chance.cc_type({ raw: true })
let number = chance.cc({ type: type.short_name })
t.is(number.length, type.length)
})
})
// chance.cc_type()
test('cc_type() returns a random credit card type', t => {
_.times(1000, () => {
t.true(_.isString(chance.cc_type()))
})
})
test('cc_type() can take a raw arg and obey it', t => {
_.times(1000, () => {
let type = chance.cc_type({ raw: true })
t.truthy(type.name)
t.truthy(type.short_name)
t.truthy(type.prefix)
t.truthy(type.length)
})
})
test('cc_type() can take a name arg and obey it', t => {
_.times(1000, () => {
let type = chance.cc_type({ name: 'Visa', raw: true })
t.is(type.name, 'Visa')
})
})
test('cc_type() with bogus type throws', t => {
const fn = () => chance.cc_type({ name: 'potato' })
t.throws(fn, 'Chance: Credit card type \'potato\' is not supported')
})
// chance.cc_types()
test('cc_types() returns an array of credit card types', t => {
t.true(_.isArray(chance.cc_types()))
})
// chance.currency()
test('currency() returns a currency', t => {
_.times(1000, () => {
let currency = chance.currency()
t.true(_.isObject(currency))
t.truthy(currency.code)
t.is(currency.code.length, 3)
t.truthy(currency.name)
})
})
// chance.currency_pair()
test('currency_pair() returns a currency pair', t => {
_.times(1000, () => {
let currency_pair = chance.currency_pair()
t.true(_.isArray(currency_pair))
t.is(currency_pair.length, 2)
t.not(currency_pair[0].code, currency_pair[1].code)
})
})
test('currency_pair() can return string version', t => {
_.times(1000, () => {
let currency_pair = chance.currency_pair(true)
t.true(_.isString(currency_pair))
t.is(currency_pair.length, 7)
t.true(/^[A-Z][A-Z][A-Z]+\/[A-Z][A-Z][A-Z]$/.test(currency_pair))
})
})
// chance.dollar()
test('dollar() returns a proper dollar amount', t => {
let dollar = chance.dollar()
t.true(/\$[0-9]+\.[0-9]+/.test(dollar))
let dollarFloat = parseFloat(dollar.substring(1, dollar.length))
t.true(dollarFloat < 10001)
})
test('dollar() obeys min and max, if provided', t => {
_.times(1000, () => {
let dollar = chance.dollar({ max: 20 })
let dollarFloat = parseFloat(dollar.substring(1, dollar.length))
t.true(dollarFloat <= 20)
})
_.times(1000, () => {
let dollar = chance.dollar({ min: 20 })
let dollarFloat = parseFloat(dollar.substring(1, dollar.length))
t.true(dollarFloat >= 20)
})
})
test('dollar() can take negative min and max', t => {
_.times(1000, () => {
let dollar = chance.dollar({ min: -200, max: -1 })
t.is(dollar.charAt(0), '-')
let dollarFloat = parseFloat(dollar.substring(2, dollar.length))
// This is necessary because we strip the - when parsing
dollarFloat *= -1
t.true(dollarFloat <= -1)
t.true(dollarFloat >= -200)
})
})
// chance.euro()
test('euro() returns a proper euro amount', t => {
let euro = chance.euro()
t.true(/[0-9]+,?\.?[0-9]+?€/.test(euro))
let euroFloat = parseFloat(euro.substring(euro.length, -1))
t.true(euroFloat < 10001)
})
// chance.exp()
test('exp() looks correct', t => {
_.times(1000, () => {
let exp = chance.exp()
t.true(_.isString(exp))
t.is(exp.length, 7)
t.true(/([0-9]{2})\/([0-9]{4})/.test(exp))
})
})
test('exp() will respect object argument', t => {
_.times(1000, () => {
let exp = chance.exp({ raw: true })
t.true(_.isObject(exp))
t.truthy(exp.month)
t.true(_.isString(exp.month))
t.truthy(exp.year)
t.true(_.isString(exp.year))
})
})
test('exp() returs a valid credit card expiration (in a future date)', t => {
_.times(1000, () => {
let exp = chance.exp({ raw: true })
let now = new Date()
let nowMonth = now.getMonth() + 1
let nowYear = now.getFullYear()
let expMonth = parseInt(exp.month, 10)
let expYear = parseInt(exp.year, 10)
t.true(expYear >= nowYear)
if (expYear === nowYear) {
t.true(expMonth >= nowMonth)
}
})
})
// chance.exp_month()
test('exp_month() returns a numeric month with leading 0', t => {
_.times(1000, () => {
let month = chance.exp_month()
t.true(_.isString(month))
t.is(month.length, 2)
})
})
// chance.exp_year()
test('exp_year() returns an expiration year', t => {
_.times(1000, () => {
let year = chance.exp_year()
t.true(_.isString(year))
let parsedYear = parseInt(year, 10)
let curYear = new Date().getFullYear()
t.true(parsedYear >= curYear)
t.true(parsedYear <= curYear + 10)
})
})
test('exp_month() will return a future month if requested', t => {
_.times(1000, () => {
let nowMonth = new Date().getMonth() + 1
let expMonth = parseInt(chance.exp_month({ future: true }), 10)
if (nowMonth !== 12) {
t.true(expMonth > nowMonth)
} else {
t.true(expMonth >= 1)
t.true(expMonth <= 12)
}
})
})
// chance.luhn_check()
test('luhn_check() properly checks if number passes the Luhn algorithm', t => {
t.true(chance.luhn_check(49927398716))
t.true(chance.luhn_check(1234567812345670))
t.false(chance.luhn_check(49927398717))
t.false(chance.luhn_check(1234567812345678))
})
test('iban() returns an iban', t => {
let iban = chance.iban()
t.true(_.isString(iban))
t.true(/^[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{1,26}$/.test(iban))
})
+433
View File
@@ -0,0 +1,433 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.capitalize()
test('capitalize() works as expected', t => {
_.times(1000, () => {
let word = chance.capitalize(chance.word())
t.true(_.isString(word))
t.true(/[A-Z]/.test(word))
})
})
// chance.n()
test('n() gives an array of n terms for the given function', t => {
let arr = chance.n(chance.email, 25, { domain: 'example.com' })
t.true(_.isArray(arr))
t.is(arr.length, 25)
arr.map((email) => {
t.true(/example\.com$/.test(email))
})
})
test('n() gives an array of 1 when n not given', t => {
let arr = chance.n(chance.email)
t.true(_.isArray(arr))
t.is(arr.length, 1)
})
test('n() throws when first argument is not a function', t => {
let testFns = [
() => chance.n(chance.character({ pool: 'abcde' }), 10),
() => chance.n('foo', 10),
() => chance.n({}, 10),
() => chance.n(null, 10),
() => chance.n(undefined, 10),
() => chance.n(21, 10),
]
testFns.map((fn) => {
t.throws(fn, 'Chance: The first argument must be a function.')
})
})
test('n() gives an empty array when n is set to 0', t => {
let arr = chance.n(chance.email, 0)
t.true(_.isArray(arr))
t.is(arr.length, 0)
})
// chance.pick()
test('pick() returns a single element when called without a count argument', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pick(arr)
t.is(picked.length, 1)
})
})
test('pick() returns a multiple elements when called with a count argument', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pick(arr, 3)
t.is(picked.length, 3)
})
})
test('pick() does not destroy the original array', t => {
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
_.times(1000, () => {
let cloned = _.clone(arr)
let picked = chance.pick(cloned, 3)
t.is(cloned.length, 6)
t.deepEqual(arr, cloned)
})
})
test('pick() throws if zero elements in array', t => {
const fn = () => chance.pick([])
t.throws(fn, 'Chance: Cannot pick() from an empty array')
})
// chance.pickone()
test('pickone() returns a single element', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickone(arr)
t.is(picked.length, 1)
t.false(_.isArray(picked))
})
})
test('pickone() throws if zero elements in array', t => {
const fn = () => chance.pickone([])
t.throws(fn, 'Chance: Cannot pickone() from an empty array')
})
// chance.pickset()
test('pickset() returns empty array when count 0', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickset(arr, 0)
t.is(picked.length, 0)
t.true(_.isArray(picked))
})
})
test('pickset() throws if zero elements in array', t => {
const fn = () => chance.pickset([])
t.throws(fn, 'Chance: Cannot pickset() from an empty array')
})
test('pickset() returns single element array if no count provided', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickset(arr)
t.is(picked.length, 1)
t.true(_.isArray(picked))
})
})
test('pickset() throws if count is not positive number', t => {
let arr = ['a', 'b', 'c', 'd']
const fn = () => chance.pickset(arr, -1)
t.throws(fn, 'Chance: Count must be a positive number')
})
test('pickset() returns single element array when called with count of 1', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickset(arr, 1)
t.is(picked.length, 1)
t.true(_.isArray(picked))
})
})
test('pickset() returns multiple elements when called with count > 1', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickset(arr, 3)
t.is(picked.length, 3)
t.true(_.isArray(picked))
})
})
test('pickset() returns no more values than the size of the array', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickset(arr, 5)
t.is(picked.length, 4)
})
})
test('pickset() does not destroy the original array', t => {
let arr = ['a', 'b', 'c', 'd', 'e', 'f'];
_.times(1000, () => {
let cloned = _.clone(arr)
let picked = chance.pickset(cloned, 3)
t.is(cloned.length, 6)
t.deepEqual(arr, cloned)
})
})
test('pickset() returns unique values', t => {
let arr = ['a', 'b', 'c', 'd']
_.times(1000, () => {
let picked = chance.pickset(arr, 4)
t.not(picked.indexOf('a'), -1)
t.not(picked.indexOf('b'), -1)
t.not(picked.indexOf('c'), -1)
t.not(picked.indexOf('d'), -1)
})
})
// chance.shuffle()
test('shuffle() returns an array of the same size', t => {
let arr = ['a', 'b', 'c', 'd', 'e']
_.times(1000, () => {
let shuffled = chance.shuffle(_.clone(arr))
t.is(shuffled.length, 5)
t.not(shuffled.indexOf('a'), -1)
})
})
test('shuffle() returns a well shuffled array', t => {
// See http://vq.io/1lEhbim checking it isn't doing that!
let arr = ['a', 'b', 'c', 'd', 'e'];
let positions = {
a: [0, 0, 0, 0, 0],
b: [0, 0, 0, 0, 0],
c: [0, 0, 0, 0, 0],
d: [0, 0, 0, 0, 0],
e: [0, 0, 0, 0, 0]
};
let shuffled = _.clone(arr)
_.times(10000, () => {
shuffled = chance.shuffle(shuffled)
shuffled.map((item, index) => {
// Accumulate the position of the item each time
positions[item][index]++
})
})
Object.keys(positions).map((index) => {
let position = positions[index]
position.map((item) => {
// This should be around 20% give or take a bit since there are
// 5 elements and they should be evenly distributed
t.true(item >= 1800)
t.true(item <= 2200)
})
})
})
test('shuffle() does not destroy original array', t => {
let arr = ['a', 'b', 'c', 'd', 'e']
_.times(1000, () => {
let cloned = _.clone(arr)
let shuffled = chance.shuffle(cloned)
t.is(shuffled.length, 5)
t.deepEqual(arr, cloned)
})
})
// chance.unique()
test('unique() gives a unique array of the selected function', t => {
_.times(500, () => {
let arr = chance.unique(chance.character, 25, { pool: "abcdefghijklmnopqrstuvwxyz" })
t.true(_.isArray(arr))
t.is(_.uniq(arr).length, 25)
})
})
test('unique() works properly with options', t => {
_.times(500, () => {
let arr = chance.unique(chance.date, 20, { year: 2016 })
t.true(_.isArray(arr))
t.is(_.uniq(arr).length, 20)
})
})
test('unique() throws when num is likely out of range', t => {
const fn = () => chance.unique(chance.character, 10, { pool: 'abcde' })
t.throws(fn, 'Chance: num is likely too large for sample set')
})
test('unique() throws when first argument is not a function', t => {
const fn = () => chance.unique(chance.character({ pool: 'abcde' }), 10)
t.throws(fn, 'Chance: The first argument must be a function.')
})
test('unique() will take a custom comparator for comparing complex objects', t => {
const comparator = (arr, val) => {
// If this is the first element, we know it doesn't exist
if (arr.length === 0) {
return false
} else {
// If a match has been found, short circuit check and just return
return arr.reduce((acc, item) => acc ? acc : item.name === val.name, false)
}
}
let arr = chance.unique(chance.currency, 25, { comparator: comparator })
t.is(_.uniq(arr).length, 25)
})
test('unique() works without a third argument', t => {
_.times(200, () => {
t.true(_.isArray(chance.unique(chance.character, 10)))
})
})
// chance.weighted()
test('weighted() returns an element', t => {
_.times(1000, () => {
let picked = chance.weighted(['a', 'b', 'c', 'd'], [1, 1, 1, 1])
t.true(_.isString(picked))
t.is(picked.length, 1)
})
})
test('weighted() works with just 2 items', t => {
// Use Math.random as the random function rather than our Mersenne twister
// just tospeed things up here because this test takes awhile to gather
// enough data to have a large enough sample size to adequately test. This
// increases speed by a few orders of magnitude at the cost of
// repeatability (which we aren't using here)
let chance = new Chance(Math.random)
var picked = { a: 0, b: 0 }
// This makes it a tad slow, but we need a large enough sample size to
// adequately test
_.times(50000, () => {
picked[chance.weighted(['a', 'b'], [1, 100])]++
})
// This range is somewhat arbitrary, but good enough to test our constraints
let ratio = picked.b / picked.a
t.true(ratio > 80)
t.true(ratio < 120)
})
test('weighted() works with trim', t => {
_.times(1000, () => {
let picked = chance.weighted(['a', 'b', 'c', 'd'], [1, 1, 1, 1], true)
t.true(_.isString(picked))
t.is(picked.length, 1)
})
})
test('weighted() throws error if called with an array of weights different from options', t => {
const fn = () => chance.weighted(['a', 'b', 'c', 'd'], [1, 2, 3])
t.throws(fn, 'Chance: Length of array and weights must match')
})
test('weighted() does not throw error if called with good weights', t => {
const fn = () => chance.weighted(['a', 'b', 'c', 'd'], [1, 2, 3, 4])
t.notThrows(fn)
})
test('weighted() throws error if weights invalid', t => {
const fn = () => chance.weighted(['a', 'b', 'c', 'd'], [0, 0, 0, 0])
t.throws(fn, 'Chance: No valid entries in array weights')
})
test('weighted() throws error if called with an array of weights different from options 2', t => {
const fn = () => chance.weighted(['a', 'b', 'c', 'd'], [1, 2, 3, 4, 5])
t.throws(fn, 'Chance: Length of array and weights must match')
})
test('weighted() throws error if weights contains NaN', t => {
const fn = () => chance.weighted(['a', 'b', 'c', 'd'], [1, NaN, 1, 1])
t.throws(fn, 'Chance: All weights must be numbers')
})
test('weighted() returns results properly weighted', t => {
// Use Math.random as the random function rather than our Mersenne twister
// just tospeed things up here because this test takes awhile to gather
// enough data to have a large enough sample size to adequately test. This
// increases speed by a few orders of magnitude at the cost of
// repeatability (which we aren't using here)
let chance = new Chance(Math.random)
let picked = { a: 0, b: 0, c: 0, d: 0 }
_.times(50000, () => {
picked[chance.weighted(['a', 'b', 'c', 'd'], [1, 100, 100, 1])]++
})
// This range is somewhat arbitrary, but good enough to test our constraints
let baRatio = picked.b / picked.a
t.true(baRatio > 60)
t.true(baRatio < 140)
let cdRatio = picked.c / picked.d
t.true(cdRatio > 60)
t.true(cdRatio < 140)
let cbRatio = (picked.c / picked.b) * 100
t.true(cbRatio > 50)
t.true(cbRatio < 150)
})
test('weighted() works with fractional weights', t => {
// Use Math.random as the random function rather than our Mersenne twister
// just tospeed things up here because this test takes awhile to gather
// enough data to have a large enough sample size to adequately test. This
// increases speed by a few orders of magnitude at the cost of
// repeatability (which we aren't using here)
let chance = new Chance(Math.random)
let picked = { a: 0, b: 0, c: 0, d: 0 }
_.times(50000, () => {
picked[chance.weighted(['a', 'b', 'c', 'd'], [0.001, 0.1, 0.1, 0.001])]++
})
// This range is somewhat arbitrary, but good enough to test our constraints
let baRatio = picked.b / picked.a
t.true(baRatio > 60)
t.true(baRatio < 140)
let cdRatio = picked.c / picked.d
t.true(cdRatio > 60)
t.true(cdRatio < 140)
let cbRatio = (picked.c / picked.b) * 100
t.true(cbRatio > 50)
t.true(cbRatio < 150)
})
test('weighted() works with weight of 0', t => {
_.times(1000, () => {
let picked = chance.weighted(['a', 'b', 'c'], [1, 0, 1])
t.true(_.isString(picked))
t.true(picked !== 'b')
})
})
test('weighted() works with negative weight', t => {
_.times(1000, () => {
let picked = chance.weighted(['a', 'b', 'c'], [1, -2, 1])
t.true(_.isString(picked))
t.true(picked !== 'b')
})
})
// chance.pad()
test('pad() always returns same number when width same as length of number', t => {
_.times(1000, () => {
let num = chance.natural({ min: 10000, max: 99999 })
let padded = chance.pad(num, 5)
t.true(_.isString(padded))
t.is(padded.length, 5)
})
})
test('pad() will pad smaller number to the right width', t => {
_.times(1000, () => {
let num = chance.natural({ max: 99999 })
let padded = chance.pad(num, 10)
t.true(_.isString(padded))
t.is(padded.length, 10)
t.not(padded.indexOf('00000'), -1)
})
})
test('pad() can take a pad e.lement', t => {
_.times(1000, () => {
let num = chance.natural({ max: 99999 })
let padded = chance.pad(num, 10, 'V')
t.true(_.isString(padded))
t.is(padded.length, 10)
t.not(padded.indexOf('VVVVV'), -1)
})
})
+298
View File
@@ -0,0 +1,298 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.coin()
test('coin() returns a coin', t => {
_.times(1000, () => {
t.true(/(heads|tails)/.test(chance.coin()))
})
})
// chance.d4()
test('d4() returns a properly bounded d4', t => {
_.times(1000, () => {
let die = chance.d4()
t.true(die >= 1)
t.true(die <= 4)
})
})
// chance.d6()
test('d6() returns a properly bounded d6', t => {
_.times(1000, () => {
let die = chance.d6()
t.true(die >= 1)
t.true(die <= 6)
})
})
// chance.d8()
test('d8() returns a properly bounded d8', t => {
_.times(1000, () => {
let die = chance.d8()
t.true(die >= 1)
t.true(die <= 8)
})
})
// chance.d10()
test('d10() returns a properly bounded d10', t => {
_.times(1000, () => {
let die = chance.d10()
t.true(die >= 1)
t.true(die <= 10)
})
})
// chance.d12()
test('d12() returns a properly bounded d12', t => {
_.times(1000, () => {
let die = chance.d12()
t.true(die >= 1)
t.true(die <= 12)
})
})
// chance.d20()
test('d20() returns a properly bounded d20', t => {
_.times(1000, () => {
let die = chance.d20()
t.true(die >= 1)
t.true(die <= 20)
})
})
// chance.d30()
test('d30() returns a properly bounded d30', t => {
_.times(1000, () => {
let die = chance.d30()
t.true(die >= 1)
t.true(die <= 30)
})
})
// chance.d100()
test('d100() returns a properly bounded d100', t => {
_.times(1000, () => {
let die = chance.d100()
t.true(die >= 1)
t.true(die <= 100)
})
})
// chance.emotion()
test('emotion() returns a random emotion', t => {
_.times(1000, () => {
let emotion = chance.emotion()
t.true(_.isString(emotion))
t.true(emotion.length >= 2)
t.true(emotion.length <= 30)
})
})
// chance.guid()
test('guid() returns a proper guid', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){8}(-([0-9a-fA-F]){4}){3}-([0-9a-fA-F]){12}/.test(chance.guid()))
})
})
test('guid() returns a proper version 1 guid', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-1([0-9a-fA-F]){3}-([ab89])([0-9a-fA-F]){3}-([0-9a-fA-F]){12}/.test(chance.guid({ version: 1 })))
})
})
test('guid() returns a proper version 2 guid', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-2([0-9a-fA-F]){3}-([ab89])([0-9a-fA-F]){3}-([0-9a-fA-F]){12}/.test(chance.guid({ version: 2 })))
})
})
test('guid() returns a proper version 3 guid', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-3([0-9a-fA-F]){3}-([ab89])([0-9a-fA-F]){3}-([0-9a-fA-F]){12}/.test(chance.guid({ version: 3 })))
})
})
test('guid() returns a proper version 4 guid', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-4([0-9a-fA-F]){3}-([ab89])([0-9a-fA-F]){3}-([0-9a-fA-F]){12}/.test(chance.guid({ version: 4 })))
})
})
test('guid() returns a proper version 5 guid', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-5([0-9a-fA-F]){3}-([ab89])([0-9a-fA-F]){3}-([0-9a-fA-F]){12}/.test(chance.guid({ version: 5 })))
})
})
// chance.hash()
test('hash() returns a proper hash', t => {
_.times(1000, () => {
let hash = chance.hash()
t.true(/([0-9a-f]){40}/.test(hash))
t.is(hash.length, 40)
})
})
test('hash() obeys length, if supplied', t => {
_.times(1000, () => {
let length = chance.natural({ min: 1, max: 64 })
let hash = chance.hash({ length: length })
t.is(hash.length, length)
})
})
// chance.mac_address()
test('mac_address() returns a proper mac address', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}/.test(chance.mac_address()))
})
})
test('mac_address() returns a proper colon separated mac address', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}:([0-9a-fA-F]){2}/.test(chance.mac_address({ separator: ':' })))
})
})
test('mac_address() returns a proper hyphen separated mac address', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){2}-([0-9a-fA-F]){2}-([0-9a-fA-F]){2}-([0-9a-fA-F]){2}-([0-9a-fA-F]){2}-([0-9a-fA-F]){2}/.test(chance.mac_address({ separator: '-' })))
})
})
test('mac_address() returns a proper network version mac address', t => {
_.times(1000, () => {
t.true(/([0-9a-fA-F]){4}.([0-9a-fA-F]){4}.([0-9a-fA-F]){4}/.test(chance.mac_address({ networkVersion: true })))
})
})
// chance.mixin()
test('mixin() works with a simple function', t => {
chance.mixin({
user: () => {
return {
first: chance.first(),
last: chance.last(),
email: chance.email()
}
}
})
t.truthy(chance.user)
_.times(1000, () => {
let user = chance.user()
t.truthy(user)
t.truthy(user.first)
t.true(_.isString(user.last))
t.true(_.isString(user.email))
})
})
test('mixin() multiple work, we can call previously defined mixins', t => {
chance.mixin({
user: () => {
return {
first: chance.first(),
last: chance.last(),
email: chance.email()
}
},
social_user: () => {
let user = chance.user()
user.network = chance.pick(['facebook', 'twitter'])
return user
}
})
t.truthy(chance.user)
t.truthy(chance.social_user)
_.times(1000, () => {
let social_user = chance.social_user()
t.truthy(social_user)
t.truthy(social_user.first)
t.truthy(social_user.network)
t.true(social_user.network === 'facebook' ||
social_user.network === 'twitter')
})
})
// chance.radio()
test('radio() works as expected', t => {
_.times(1000, () => {
let radio = chance.radio()
t.true(_.isString(radio))
t.is(radio.length, 4)
t.true(/^[KW][A-Z][A-Z][A-Z]/.test(radio))
})
})
test('radio() accepts east', t => {
_.times(1000, () => {
let radio = chance.radio({ side: 'east' })
t.true(_.isString(radio))
t.is(radio.length, 4)
t.true(/^[W][A-Z][A-Z][A-Z]/.test(radio))
})
})
test('radio() accepts west', t => {
_.times(1000, () => {
let radio = chance.radio({ side: 'west' })
t.true(_.isString(radio))
t.is(radio.length, 4)
t.true(/^[K][A-Z][A-Z][A-Z]/.test(radio))
})
})
// chance.rpg()
test('rpg() appears to work as expected', t => {
_.times(1000, () => {
let dice = chance.rpg('5d20')
t.true(_.isArray(dice))
t.is(dice.length, 5)
dice.map((die) => {
t.true(die >= 1)
t.true(die <= 20)
})
})
})
test('rpg() without a die roll throws an error', t => {
t.throws(() => chance.rpg(), 'Chance: A type of die roll must be included')
})
test('rpg() throws errors where it should', t => {
const errorFns = [
() => chance.rpg('3'),
() => chance.rpg('hd23'),
() => chance.rpg('3d23d2'),
() => chance.rpg('d20')
]
errorFns.map((fn) => {
t.throws(fn, 'Chance: Invalid format provided. Please provide #d# where the first # is the number of dice to roll, the second # is the max of each die')
})
})
test('rpg() will take and obey a sum', t => {
_.times(1000, () => {
let rpg = chance.rpg('4d20', { sum: true })
t.true(_.isNumber(rpg))
t.true(rpg >= 4)
t.true(rpg <= 80)
})
})
// chance.tv()
test('tv() works as expected', t => {
_.times(1000, () => {
let tv = chance.tv()
t.true(_.isString(tv))
t.is(tv.length, 4)
t.true(/^[KW][A-Z][A-Z][A-Z]/.test(tv))
})
})
+29
View File
@@ -0,0 +1,29 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.android_id()
test('android_id() returns a proper android id', t => {
_.times(1000, () => t.true(/APA91([0-9a-zA-Z-_]){178}/.test(chance.android_id())))
})
// chance.apple_token()
test('apple_token() returns a proper apple push token', t => {
_.times(1000, () => t.true(/([0-9a-fA-F]){64}/.test(chance.apple_token())))
})
// chance.wp8_anid2()
test('wp8_anid2() returns a proper windows phone 8 anid2', t => {
_.times(1000, () => t.true(/^([0-9a-zA-Z]){43}=$/.test(chance.wp8_anid2())))
})
// chance.wp7_anid()
test('wp7_anid() returns a proper windows phone 7 anid', t => {
_.times(1000, () => t.true(/^A=[0-9A-F]{32}&E=[0-9a-f]{3}&W=\d$/.test(chance.wp7_anid())))
})
test('bb_pin() returns a proper blackberry pin', t => {
_.times(1000, () => t.true(/([0-9a-f]){8}/.test(chance.bb_pin())))
})
+52
View File
@@ -0,0 +1,52 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.note()
test('note() returns a valid note', t => {
_.times(1000, () => {
let note = chance.note()
t.true(_.isString(note))
t.true(note.length <= 2)
})
})
// chance.midi_note()
test('midi_note() returns a valid midi note between 0 and 127', t => {
_.times(1000, () => {
let midi_note = chance.midi_note()
t.true(_.isNumber(midi_note))
t.true(midi_note >= 0)
t.true(midi_note <= 127)
})
})
// chance.chord_quality()
test('chord_quality() returns a valid chord quality', t => {
_.times(1000, () => {
let chord_quality = chance.chord_quality()
t.true(_.isString(chord_quality))
t.true(chord_quality.length <= 4)
})
})
// chance.chord()
test('chord() returns a valid chord', t => {
_.times(1000, () => {
let chord = chance.chord()
t.true(_.isString(chord))
t.true(chord.length <= 6)
})
})
// chance.tempo()
test('tempo() returns a valid tempo between 40 and 320', t => {
_.times(1000, () => {
let tempo = chance.tempo()
t.true(_.isNumber(tempo))
t.true(tempo >= 40)
t.true(tempo <= 320)
})
})
+114
View File
@@ -0,0 +1,114 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
// Helper methods
const mean = (arr) => arr.reduce((a, b) => a + b)/arr.length
const stddev = (arr) => {
var testMean = mean(arr)
var deviation = arr.map((item) => (item - testMean) * (item - testMean))
return Math.sqrt(deviation.reduce((a, b) => a + b )/arr.length)
}
const pool = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
const chance = new Chance()
test('normal() works as expected with no parameters and returns a number', t => {
_.times(1000, () => {
let norm = chance.normal()
t.is(typeof norm, 'number')
})
})
test('normal() returns values fairly close to the expected standard deviation and mean', t => {
let testStddev = 1
let testMean = 0
let group = chance.n(chance.normal, 10000)
t.true(Math.abs(mean(group) - testMean) < testStddev)
t.true(Math.abs(stddev(group) - testStddev) < testStddev * 0.05)
})
test('normal() works as expected with a pool of custom values provided', t => {
let testStddev = 0.0000000001
let testMean = 2
_.times(1000, () => {
let norm = chance.normal({ mean: testMean, dev: testStddev, pool: pool })
t.true(pool.indexOf(norm) !== -1)
})
})
test('normal() recalculates and returns a value even if the normal() results in indexes outside the bounds of the pool', t => {
let testStddev = 1.5
let testMean = 3
_.times(1000, () => {
let norm = chance.normal({ mean: testMean, dev: testStddev, pool: pool })
t.true(pool.indexOf(norm) !== -1)
})
})
test('normal() can be used with other chance functions', t => {
let testStddev = 1
let testMean = 3
let group = chance.n(chance.normal, 1000, { mean: testMean, dev: testStddev, pool: pool })
t.true(group.length === 1000)
t.true(pool.indexOf(group[0]) !== -1)
t.true(pool.indexOf(group[999]) !== -1)
})
test('normal() should produce a correctly distributed group of pool items', t => {
let testStddev = 2
let testMean = 6
let group = chance.n(chance.normal, 10000, { mean: testMean, dev: testStddev, pool: pool })
let counts = _.countBy(group)
t.true(counts.Sunday > counts.Saturday)
t.true(counts.Saturday > counts.Friday)
t.true(counts.Friday > counts.Thursday)
t.true(counts.Thursday > counts.Wednesday)
t.true(counts.Wednesday > counts.Tuesday)
t.true(counts.Tuesday > counts.Monday)
})
test('normal() should throw an error quickly if the user has provided bad pool', t => {
let testStddev = 5
let testMean = 200
const fn = () => chance.normal({ mean: testMean, dev: testStddev, pool: pool })
t.throws(fn, 'Chance: Your pool is too small for the given mean and standard deviation. Please adjust.')
})
test('normal() should throw an error if called with non-number mean', t => {
let testStddev = 5
let testMean = []
const fn = () => chance.normal({ mean: testMean, dev: testStddev, pool: pool })
t.throws(fn, 'Chance: Mean (mean) must be a number')
})
test('normal() should throw an error if called with non-number stddev', t => {
let testStddev = []
let testMean = 5
const fn = () => chance.normal({ mean: testMean, dev: testStddev, pool: pool })
t.throws(fn, 'Chance: Standard deviation (dev) must be a number')
})
test('normal() should throw an error if the pool provided is not an array', t => {
const fn = () => chance.normal({ pool: 'not an array' })
t.throws(fn, 'Chance: The pool option must be a valid array.')
})
test('normal() should work with objects', t => {
let testStddev = 1
let testMean = 1
let group = chance.n(chance.normal, 50, { mean: testMean, dev: testStddev, pool: [
{ a: 1, b: 10},
{ a: 2, b: 20},
{ a: 3, b: 30}
]})
t.true(group.length === 50)
t.truthy(group[0]['a'])
})
+447
View File
@@ -0,0 +1,447 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// age constants
const CHILD_AGE_MIN = 0
const CHILD_AGE_MAX = 12
const TEEN_AGE_MIN = 13
const TEEN_AGE_MAX = 19
const ADULT_AGE_MIN = 18
const ADULT_AGE_MAX = 65
const SENIOR_AGE_MIN = 65
const SENIOR_AGE_MAX = 100
const AGE_MIN = 0
const AGE_MAX = 100
const currentYear = new Date().getFullYear()
// chance.age()
test('age() returns a random age within expected bounds', t => {
_.times(1000, () => {
let age = chance.age()
t.true(_.isNumber(age))
t.true(age >= ADULT_AGE_MIN)
t.true(age <= ADULT_AGE_MAX)
})
})
test('age() returns a random age within expected bounds for all', t => {
_.times(1000, () => {
let age = chance.age({ type: 'all' })
t.true(_.isNumber(age))
t.true(age >= AGE_MIN)
t.true(age <= AGE_MAX)
})
})
test('age() returns a proper age for a child', t => {
_.times(1000, () => {
let age = chance.age({ type: 'child' })
t.true(_.isNumber(age))
t.true(age >= CHILD_AGE_MIN)
t.true(age <= CHILD_AGE_MAX)
})
})
test('age() returns a proper age for a teen', t => {
_.times(1000, () => {
let age = chance.age({ type: 'teen' })
t.true(_.isNumber(age))
t.true(age >= TEEN_AGE_MIN)
t.true(age <= TEEN_AGE_MAX)
})
})
test('age() returns a proper age for an adult', t => {
_.times(1000, () => {
let age = chance.age({ type: 'adult' })
t.true(_.isNumber(age))
t.true(age >= ADULT_AGE_MIN)
t.true(age <= ADULT_AGE_MAX)
})
})
test('age() returns a proper age for a senior', t => {
_.times(1000, () => {
let age = chance.age({ type: 'senior' })
t.true(_.isNumber(age))
t.true(age >= SENIOR_AGE_MIN)
t.true(age <= SENIOR_AGE_MAX)
})
})
// chance.birthday()
test('birthday() works as expected', t => {
_.times(1000, () => {
let birthday = chance.birthday()
t.true(_.isDate(birthday))
let year = birthday.getFullYear()
let curYear = new Date().getFullYear()
t.true(year > (curYear - AGE_MAX))
t.true(year < curYear)
})
})
test('birthday() can have a string returned', t => {
_.times(1000, () => {
let birthday = chance.birthday({ string: true })
t.true(_.isString(birthday))
t.false(_.isDate(birthday))
t.true(/^[0-9][0-9]?\/[0-9][0-9]?\/[0-9]{4}/m.test(birthday))
})
})
test('birthday() can have a year specified', t => {
_.times(1000, () => {
t.is(chance.birthday({ year: 1983 }).getFullYear(), 1983)
})
})
test('birthday() can have an age range specified for an adult', t => {
_.times(1000, () => {
let birthday = chance.birthday({ type: 'adult' })
let min = new Date().setFullYear(currentYear - ADULT_AGE_MAX - 1)
let max = new Date().setFullYear(currentYear - ADULT_AGE_MIN)
t.true(birthday.getTime() >= min)
t.true(birthday.getTime() <= max)
})
})
test('birthday() can have an age range specified for a teen', t => {
_.times(1000, () => {
let birthday = chance.birthday({ type: 'teen' })
let min = new Date().setFullYear(currentYear - TEEN_AGE_MAX - 1)
let max = new Date().setFullYear(currentYear - TEEN_AGE_MIN)
t.true(birthday.getTime() >= min)
t.true(birthday.getTime() <= max)
})
})
test('birthday() can have an age range specified for a child', t => {
_.times(1000, () => {
let birthday = chance.birthday({ type: 'child' })
let min = new Date().setFullYear(currentYear - CHILD_AGE_MAX - 1)
let max = new Date().setFullYear(currentYear - CHILD_AGE_MIN)
t.true(birthday.getTime() >= min)
t.true(birthday.getTime() <= max)
})
})
test('birthday() can have an age range specified for a senior', t => {
_.times(1000, () => {
let birthday = chance.birthday({ type: 'senior' })
let min = new Date().setFullYear(currentYear - SENIOR_AGE_MAX - 1)
let max = new Date().setFullYear(currentYear - SENIOR_AGE_MIN)
t.true(birthday.getTime() >= min)
t.true(birthday.getTime() <= max)
})
})
// chance.cnpj()
test('cnpj() returns a random cnpj', t => {
_.times(1000, () => {
let hidn = chance.HIDN()
t.true(_.isString(hidn))
})
})
// chance.company()
test('company() returns a random company', t => {
_.times(1000, () => {
let company = chance.company()
t.true(_.isString(company))
t.true(company.length > 4)
})
})
// chance.cpf()
test('cpf() returns a random valid taxpayer number for Brazil citizens (CPF)', t => {
_.times(1000, () => {
let cpf = chance.cpf()
t.true(_.isString(cpf))
t.true(/^\d{3}.\d{3}.\d{3}-\d{2}$/m.test(cpf))
t.is(cpf.length, 14)
})
})
// chance.first()
test('first() returns a random first name', t => {
_.times(1000, () => {
let first = chance.first()
t.true(_.isString(first))
t.true(first.length >= 2)
t.true(first.length <= 20)
t.is(first.split(' ').length, 1)
})
})
// chance.gender()
test('gender() returns a random gender', t => {
_.times(1000, () => t.true(/(Male|Female)/.test(chance.gender())))
})
test('gender() can take extra genders', t => {
_.times(1000, () => {
let gender = chance.gender({ extraGenders: ['Unknown', 'Transgender'] })
t.true(/(Male|Female|Unknown|Transgender)/.test(gender))
})
})
// chance.HIDN()
test('HIDN() returns a random HIDN', t => {
_.times(1000, () => {
let hidn = chance.HIDN()
t.true(_.isString(hidn))
t.true(/^\d{6}[A-Z]{2}$/m.test(hidn))
t.is(hidn.length, 8)
})
})
// chance.israelId()
test('israelId() returns a valid Isreal id', t => {
let id = chance.israelId()
t.true(_.isString(id))
t.is(id.length, 9)
let acc = 0
for (let i = 0; i < 8; i++) {
let thisDigit = id[i] * ( i / 2 === parseInt(i/2, 10) ? 1 : 2)
thisDigit = chance.pad(thisDigit, 2)
thisDigit = parseInt(thisDigit[0], 10) + parseInt(thisDigit[1], 10)
acc += thisDigit
}
let lastDigit = (10 - parseInt(acc.toString().slice(-1), 10).toString().slice(-1)).toString().slice(-1)
t.is(id[8], lastDigit)
})
// chance.last()
test('last() returns a random last name', t => {
_.times(1000, () => {
let last = chance.last()
t.true(_.isString(last))
t.true(last.length >= 2)
t.true(last.length <= 20)
t.true(last.split(' ').length <= 3)
})
})
// chance.name()
test('name() returns a random name', t => {
_.times(1000, () => {
let name = chance.name()
t.true(_.isString(name))
t.true(name.length >= 2)
t.true(name.length <= 30)
t.is(name.split(' ').length, 2)
t.true(/[a-zA-Z]+\ [a-zA-Z]+/.test(name))
})
})
test('name() can have the middle name specified', t => {
_.times(1000, () => {
let name = chance.name({ middle: true })
t.true(_.isString(name))
t.is(name.split(' ').length, 3)
t.true(/[a-zA-Z]+\ [a-zA-Z]+\ [a-zA-Z]+/.test(name))
})
})
test('name() can have the middle initial specified', t => {
_.times(1000, () => {
let name = chance.name({ middle_initial: true })
t.true(_.isString(name))
t.is(name.split(' ').length, 3)
t.true(/[a-zA-Z]+\ [a-zA-Z]\.\ [a-zA-Z]+/.test(name))
})
})
test('name() can have the prefix specified', t => {
_.times(1000, () => {
let name = chance.name({ prefix: true })
t.true(_.isString(name))
t.is(name.split(' ').length, 3)
t.true(/[a-zA-Z]{2,4}\.? [a-zA-Z]+\ [a-zA-Z]+/.test(name))
})
})
test('name() can have the suffix specified', t => {
_.times(1000, () => {
let name = chance.name({ suffix: true })
t.true(_.isString(name))
t.is(name.split(' ').length, 3)
t.true(/[a-zA-Z]+\ [a-zA-Z]+\ [a-zA-Z\.]+/.test(name))
})
})
// chance.name_prefix()
test('name_prefix() returns a random prefix', t => {
_.times(1000, () => {
let prefix = chance.name_prefix()
t.true(_.isString(prefix))
t.true(prefix.length < 5)
})
})
test('name_prefix() returns a correctly gendered prefix', t => {
_.times(1000, () => {
let prefix = chance.name_prefix({ gender: 'female' })
t.not(prefix, 'Mr.')
prefix = chance.name_prefix({ gender: 'male' })
t.not(prefix, 'Mrs.')
t.not(prefix, 'Miss')
})
})
test('name_prefix() can return a full prefix', t => {
_.times(1000, () => {
let prefix = chance.name_prefix({ full: true })
t.true(_.isString(prefix))
t.true(prefix.length > 3)
})
})
// chance.name_suffix()
test('name_suffix() returns a random suffix', t => {
_.times(1000, () => {
let suffix = chance.name_suffix()
t.true(_.isString(suffix))
t.true(suffix.length < 7)
})
})
test('name_suffix() can return a full suffix', t => {
_.times(1000, () => {
let suffix = chance.name_suffix({ full: true })
t.true(_.isString(suffix))
t.true(suffix.length > 5)
})
})
// chance.nationality()
test('nationality() returns a nationality that looks right', t => {
_.times(1000, () => {
let nationality = chance.nationality()
t.true(_.isString(nationality))
t.true(nationality.length > 3)
t.true(nationality.length < 26)
})
})
// chance.profession()
test('profession() returns a random profession', t => {
_.times(1000, () => {
let profession = chance.profession()
t.true(_.isString(profession))
t.true(profession.length > 3)
})
})
test('profession() returns a ranked profession', t => {
_.times(1000, () => {
let profession = chance.profession({ rank: true })
t.true(_.isString(profession))
t.true(profession.split(' ').length > 1)
t.true(/(Apprentice|Junior|Senior|Lead)/.test(profession.split(' ')[0]))
})
})
// chance.ssn()
test('ssn() returns a random social security number', t => {
_.times(1000, () => {
let ssn = chance.ssn()
t.true(_.isString(ssn))
t.true(/^\d{3}-\d{2}-\d{4}$/m.test(ssn))
t.is(ssn.length, 11)
})
})
test('ssn() can return just the last 4', t => {
_.times(1000, () => {
let ssn = chance.ssn({ ssnFour: true })
t.true(_.isString(ssn))
t.true(/^\d{4}$/m.test(ssn))
t.is(ssn.length, 4)
})
})
// chance.aadhar()
test('aadhar() returns a random aadhar number with whitespace as separator', t => {
_.times(1000, () => {
let aadhar = chance.aadhar()
t.true(_.isString(aadhar))
t.true(/^\d{4}\s\d{4}\s\d{4}$/m.test(aadhar))
t.is(aadhar.length, 14)
})
})
// chance.aadhar({separatedByWhiteSpace : false})
test('aadhar() returns a random aadhar number with no separator', t => {
_.times(1000, () => {
let aadhar = chance.aadhar({separatedByWhiteSpace : false})
t.true(_.isString(aadhar))
t.true(/^\d{12}$/m.test(aadhar))
t.is(aadhar.length, 12)
})
})
// chance.aadhar({onlyLastFour : true})
test('aadhar() can return just the last 4', t => {
_.times(1000, () => {
let aadhar = chance.aadhar({ onlyLastFour: true })
t.true(_.isString(aadhar))
t.true(/^\d{4}$/m.test(aadhar))
t.is(aadhar.length, 4)
})
})
// chance.suffix()
test('suffix() returns a random suffix', t => {
_.times(1000, () => {
let suffix = chance.suffix()
t.true(_.isString(suffix))
t.true(suffix.length < 7)
})
})
test('suffix() returns a full random suffix', t => {
_.times(1000, () => {
let suffix = chance.suffix({ full: true })
t.true(_.isString(suffix))
t.true(suffix.length > 5)
})
})
// chance.mrz()
test('mrz() should return a valid passport number', t => {
let sample = "P<GBRFOLKS<<JOANNE<<<<<<<<<<<<<<<<<<<<<<<<<<2321126135GBR6902069F1601013<<<<<<<<<<<<<<02"
let mrz = chance.mrz({
first: 'Joanne',
last: 'Folks',
gender: 'F',
dob: '690206',
expiry: '160101',
passportNumber: '232112613',
})
t.is(sample, mrz)
sample = "P<GBRKELLY<<LIDA<<<<<<<<<<<<<<<<<<<<<<<<<<<<3071365913GBR6606068F2003131<<<<<<<<<<<<<<04"
mrz = chance.mrz({
first: 'Lida',
last: 'Kelly',
gender: 'F',
dob: '660606',
expiry: '200313',
passportNumber: '307136591',
})
t.is(sample, mrz)
})
test('mrz() should return a valid random passport number when not given any inputs', t => {
let mrz = chance.mrz()
t.true(_.isString(mrz))
t.is(mrz.substr(0, 5), 'P<GBR')
t.is(mrz.length, 88)
t.true(/^[A-Z0-9<]{9}[0-9]{1}[A-Z]{3}[0-9]{7}[A-Z]{1}[0-9]{7}[A-Z0-9<]{14}[0-9]{2}$/.test(mrz.substr(44)))
})
+116
View File
@@ -0,0 +1,116 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.cf()
test('cf() returns a valid random cf', t => {
_.times(1000, () => {
let cf = chance.cf()
t.true(_.isString(cf))
t.is(cf.length, 16)
t.true(/[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]/.test(cf))
})
})
test('cf() returns a consistent cf', t => {
let testCases = [{
item: {
first: 'Aldo',
last: 'Fabrizi',
gender: 'Male',
birthday: new Date(1905,10,1),
city: 'h501'
},
cf: 'FBRLDA05S01H501A'
}, {
item: {
first: 'Sophia',
last: 'Loren',
gender: 'Female',
birthday: new Date(1934,8,20),
city: 'h501'
},
cf: 'LRNSPH34P60H501G'
}, {
item: {
first: 'Claudia',
last: 'Cardinale',
gender: 'Female',
birthday: new Date(1938,3,15),
city: 'z352'
},
cf: 'CRDCLD38D55Z352Q'
}, {
item: {
first: 'Sergio',
last: 'Leone',
gender: 'Male',
birthday: new Date(1929,0,3),
city: 'h501'
},
cf: 'LNESRG29A03H501W'
}, {
item: {
first: 'Claudio',
last: 'Marchisio',
gender: 'Male',
birthday: new Date(1986,0,19),
city: 'l219'
},
cf: 'MRCCLD86A19L219F'
}, {
item: {
first: 'Eu',
last: 'Ho',
gender: 'Male',
birthday: new Date(2012,3,12),
city: 'z210'
},
cf: 'HOXEUX12D12Z210Q'
}];
testCases.map((test) => {
t.is(chance.cf(test.item), test.cf)
})
})
// chance.pl_nip()
test('pl_nip() returns a valid NIP number', t => {
_.times(1000, () => {
let nip = chance.pl_nip()
t.true(_.isString(nip))
t.is(nip.length, 10)
})
})
// chance.pl_pesel()
test('pl_pesel() returns a valid PESEL number', t => {
_.times(1000, () => {
let pesel = chance.pl_pesel()
t.true(_.isString(pesel))
t.is(pesel.length, 11)
})
})
// chance.pl_regon()
test('pl_regon() returns a valid REGON number', t => {
_.times(1000, () => {
let regon = chance.pl_regon()
t.true(_.isString(regon))
t.is(regon.length, 9)
})
})
// chance.vat()
test('vat() returns a valid italian vat number', t => {
_.times(1000, () => {
let vat = chance.vat({ country: 'it' })
t.true(_.isString(vat))
t.is(vat.length, 11)
let first = vat.charAt(0)
t.true(first === '0' || first === '1')
t.true(chance.luhn_check(vat))
})
})
+123
View File
@@ -0,0 +1,123 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.sentence()
test('sentence() returns a random sentence', t => {
_.times(1000, () => {
let sentence = chance.sentence()
t.true(_.isString(sentence))
let len = sentence.split(' ').length
t.true(len > 11)
t.true(len < 19)
})
})
test('sentence() will obey bounds', t => {
_.times(1000, () => {
let sentence = chance.sentence({ words: 5 })
t.true(_.isString(sentence))
t.is(sentence.split(' ').length, 5)
t.true(/[a-zA-Z]+ [a-zA-Z]+ [a-zA-Z]+ [a-zA-Z]+ [a-zA-Z]+.?/m.test(sentence))
})
})
// chance.syllable()
test('syllable() returns a random syllable', t => {
_.times(1000, () => {
let syllable = chance.syllable()
t.true(_.isString(syllable))
t.true(syllable.length > 1)
t.true(syllable.length < 4)
})
})
test('syllable() obeys the capitalize option', t => {
_.times(1000, () => {
let syllable = chance.syllable({ capitalize: true })
t.true(_.isString(syllable))
t.true(syllable.length > 1)
t.true(syllable.length < 4)
t.true(/[A-Z]+/.test(syllable))
})
})
// chance.word()
test('word() returns a random word', t => {
_.times(1000, () => {
let word = chance.word()
t.true(_.isString(word))
t.true(word.length > 1)
t.true(word.length < 10)
})
})
test('word() obeys the capitalize option', t => {
_.times(1000, () => {
let word = chance.word({ capitalize: true })
t.true(_.isString(word))
t.true(word.length > 1)
t.true(word.length < 10)
t.true(word.charAt(0) === word.charAt(0).toUpperCase())
})
})
test('word() can have a set number of syllables', t => {
_.times(1000, () => {
let word = chance.word({ syllables: 3 })
t.true(_.isString(word))
t.true(word.length > 5)
t.true(word.length < 10)
})
})
test('word() can have a set length', t => {
_.times(1000, () => {
let word = chance.word({ length: 5 })
t.true(_.isString(word))
t.is(word.length, 5)
})
})
test('word() throws if both syllables and length specified', t => {
const fn = () => chance.word({ syllables: 3, length: 20 })
t.throws(fn, 'Chance: Cannot specify both syllables AND length.')
})
// chance.paragraph()
test('paragraph() returns a random paragraph', t => {
_.times(100, () => {
let paragraph = chance.paragraph()
t.true(_.isString(paragraph))
let len = paragraph.split('.').length
t.true(len > 2)
t.true(len < 9)
})
})
test('paragraph() will obey bounds', t => {
_.times(100, () => {
let paragraph = chance.paragraph({ sentences: 5 })
t.true(_.isString(paragraph))
// Have to account for the fact that the period at the end will add
// to the count of sentences. This is the fault of our hackish way
// of detecting sentences -- by splitting on '.'
let len = paragraph.split('.').length
t.is(len, 6)
})
})
test('paragraph) will obey line breaks', t => {
_.times(100, () => {
let rand = _.random(1, 50);
let paragraph = chance.paragraph({ sentences: rand, linebreak: true })
t.true(_.isString(paragraph))
let len = paragraph.split('\n').length
t.is(len, rand);
})
})
+299
View File
@@ -0,0 +1,299 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.ampm()
test('ampm() returns am or pm', t => {
_.times(1000, () => {
let ampm = chance.ampm()
t.true(_.isString(ampm))
t.true(/^([ap]m)$/m.test(ampm))
})
})
// chance.date()
test('date() returns a random date', t => {
_.times(1000, () => {
let date = chance.date()
t.true(_.isDate(date))
t.truthy(date.getTime())
})
})
test('date() accepts an american option', t => {
_.times(1000, () => {
let date = chance.date({ american: chance.bool() })
t.true(_.isDate(date))
t.truthy(date.getTime())
})
})
test('date() can have some default provided and obey them', t => {
_.times(1000, () => {
// One of each month type in terms of number of days.
let month = [0, 1, 3][Math.floor(Math.random() * 3)]
let date = chance.date({ year: 1983 })
t.true(_.isDate(date))
t.is(date.getFullYear(), 1983)
date = chance.date({ month: month })
t.true(_.isDate(date))
t.is(date.getMonth(), month)
date = chance.date({ day: 21 })
t.true(_.isDate(date))
t.is(date.getDate(), 21)
})
})
test('date() can specify min and max', t => {
_.times(1000, () => {
let bounds = {
min: new Date(),
max: new Date(new Date().getTime() + 1234567890123),
}
let date = chance.date(bounds)
t.true(_.isDate(date))
t.true(date >= bounds.min)
t.true(date <= bounds.max)
})
})
test('date() returns a date, can specify just min', t => {
_.times(1000, () => {
let bounds = { min: new Date() }
let date = chance.date(bounds)
t.true(_.isDate(date))
t.true(date >= bounds.min)
})
})
test('date() returns a date, can specify just max', t => {
_.times(1000, () => {
let bounds = { max: new Date() }
let date = chance.date(bounds)
t.true(_.isDate(date))
t.true(date <= bounds.max)
})
})
test('date() can return a string date', t => {
_.times(1000, () => {
let date = chance.date({ string: true })
t.true(_.isString(date))
t.true(/^[0-9][0-9]?\/[0-9][0-9]?\/[0-9]{4}/m.test(date))
})
})
// chance.hammertime()
test('hammertime() works', t => {
_.times(1000, () => {
let hammertime = chance.hammertime()
t.true(_.isNumber(hammertime))
t.true(hammertime > 0)
t.true(hammertime < 8640000000000000)
})
})
// chance.hour()
test('hour() returns an hour', t => {
_.times(1000, () => {
let hour = chance.hour()
t.true(_.isNumber(hour))
t.true(hour >= 1)
t.true(hour <= 12)
})
})
test('hour() returns an hour in 24 hour format', t => {
_.times(1000, () => {
let hour = chance.hour({ twentyfour: true })
t.true(_.isNumber(hour))
t.true(hour >= 0)
t.true(hour <= 23)
})
})
test('hour() returns an hour, can specify min and max', t => {
_.times(1000, () => {
let hour = chance.hour({ min: 7, max: 10 })
t.true(_.isNumber(hour))
t.true(hour >= 7)
t.true(hour <= 10)
})
})
test('hour() returns an hour, can specify just min', t => {
_.times(1000, () => {
let hour = chance.hour({ min: 7 })
t.true(_.isNumber(hour))
t.true(hour >= 7)
t.true(hour <= 12)
})
})
test('hour() returns an hour, can specify just max', t => {
_.times(1000, () => {
let hour = chance.hour({ max: 10 })
t.true(_.isNumber(hour))
t.true(hour >= 1)
t.true(hour <= 10)
})
})
// chance.minute()
test('minute() returns a minute', t => {
_.times(1000, () => {
let minute = chance.minute()
t.true(_.isNumber(minute))
t.true(minute >= 0)
t.true(minute <= 59)
})
})
test('minute() returns an minute, can specify min and max', t => {
_.times(1000, () => {
let minute = chance.minute({ min: 18, max: 35 })
t.true(_.isNumber(minute))
t.true(minute >= 18)
t.true(minute <= 35)
})
})
test('minute() returns an minute, can specify just min', t => {
_.times(1000, () => {
let minute = chance.minute({ min: 5 })
t.true(_.isNumber(minute))
t.true(minute >= 5)
t.true(minute <= 59)
})
})
test('minute() returns an minute, can specify just max', t => {
_.times(1000, () => {
let minute = chance.minute({ max: 32 })
t.true(_.isNumber(minute))
t.true(minute >= 0)
t.true(minute <= 32)
})
})
test('month() returns a month', t => {
_.times(1000, () => {
let month = chance.month()
t.true(_.isString(month))
})
})
test('month() will return a raw month', t => {
_.times(1000, () => {
let month = chance.month({ raw: true })
t.false(_.isString(month))
t.true(_.isObject(month))
})
})
test('month() returns a month, can specify min and max', t => {
_.times(1000, () => {
let month = chance.month({raw: true, min: 5, max: 10})
t.false(_.isString(month))
t.true(month.numeric >= 5)
t.true(month.numeric <= 10)
})
})
test('month() returns a month, can specify just min', t => {
_.times(1000, () => {
let month = chance.month({raw: true, min: 5})
t.false(_.isString(month))
t.true(month.numeric >= 5)
t.true(month.numeric <= 12)
})
})
test('month() returns a month, can specify just max', t => {
_.times(1000, () => {
let month = chance.month({raw: true, max: 7})
t.false(_.isString(month))
t.true(month.numeric >= 1)
t.true(month.numeric <= 7)
})
})
// chance.timestamp()
test('timestamp() returns a timestamp', t => {
_.times(1000, () => {
let timestamp = chance.timestamp()
t.true(_.isNumber(timestamp))
t.true(timestamp > 0)
t.true(timestamp <= parseInt(new Date().getTime() / 1000, 10))
})
})
// chance.timezone()
test('timezone() returns a timezone', t => {
_.times(1000, () => {
let timezone = chance.timezone()
t.true(_.isString(timezone.name))
t.true(timezone.abbr.length < 6)
t.true(_.isNumber(timezone.offset))
})
})
// chance.weekday()
test('weekday() will return a weekday as a string', t => {
_.times(1000, () => {
let weekday = chance.weekday()
t.true(_.isString(weekday))
})
})
test('weekday() can take work: true and obey it', t => {
_.times(1000, () => {
let weekday = chance.weekday({ weekday_only: true })
t.true(_.isString(weekday))
t.not(weekday, 'Saturday')
t.not(weekday, 'Sunday')
})
})
// chance.year()
test('year() returns a year, default between today and a century after', t => {
_.times(1000, () => {
let year = chance.year()
t.true(_.isString(year))
t.true(year >= new Date().getFullYear())
t.true(year <= new Date().getFullYear() + 100)
})
})
test('year() returns a year, can specify min and max', t => {
_.times(1000, () => {
let year = chance.year({ min: 2500, max: 2600 })
t.true(_.isString(year))
t.true(year >= 2500)
t.true(year <= 2600)
})
})
test('year() returns a year, can specify just min', t => {
_.times(1000, () => {
let year = chance.year({ min: 2500 })
t.true(_.isString(year))
t.true(year >= 2500)
})
})
test('year() returns a year, can specify just max', t => {
_.times(1000, () => {
let year = chance.year({ max: 2500 })
t.true(_.isString(year))
t.true(year <= 2501)
// Ensure year not negative. Perhaps add BCE/AD and such later,
// but for now just positive is good enough.
t.true(year >= 0)
})
})
+597
View File
@@ -0,0 +1,597 @@
import test from 'ava'
import Chance from '../chance.js'
import _ from 'lodash'
const chance = new Chance()
// chance.avatar()
test('avatar() returns a legit avatar', t => {
_.times(1000, () => {
let avatar = chance.avatar()
t.true(_.isString(avatar))
t.is(avatar.split('/').length, 5)
})
})
test('avatar() can take and ignore an invalid protocol', t => {
_.times(1000, () => {
let avatar = chance.avatar({ protocol: 'invalid' })
t.true(_.isString(avatar))
t.is(avatar.indexOf('//'), 0)
})
})
test('avatar() can take and respect a protocol', t => {
const protocols = ['http', 'https']
_.times(500, () => {
protocols.map((protocol) => {
let avatar = chance.avatar({ protocol: protocol })
t.true(_.isString(avatar))
t.is(avatar.indexOf(protocol + ":"), 0)
})
})
})
test('avatar() can take and respect email', t => {
_.times(1000, () => {
let avatar = chance.avatar({ email: chance.email() })
t.true(_.isString(avatar))
t.is(avatar.split('/').length, 5)
})
})
test('avatar() can take and ignore an invalid file extension', t => {
_.times(1000, () => {
let avatar = chance.avatar({ fileExtension: 'invalid' })
t.true(_.isString(avatar))
t.false(avatar.includes('.jpg'))
t.false(avatar.includes('.png'))
t.false(avatar.includes('.gif'))
})
})
test('avatar() can take and respect a legit file extension', t => {
let file_types = ['bmp', 'gif', 'jpg', 'png']
_.times(250, () => {
_.times(file_types.length, (index) => {
let avatar = chance.avatar({ fileExtension: file_types[index] })
t.true(_.isString(avatar))
t.true(avatar.includes('.' + file_types[index]))
})
})
})
test('avatar() can take and ignore an invalid size', t => {
_.times(1000, () => {
let avatar = chance.avatar({ size: 'abc' })
t.true(_.isString(avatar))
t.false(avatar.includes('&s='))
})
})
test('avatar() can take and respect a legit size', t => {
_.times(1000, (index) => {
let avatar = chance.avatar({ size: index + 1 })
t.true(_.isString(avatar))
t.true(avatar.includes('&s=' + (index + 1).toString()))
})
})
test('avatar() can take and ignore an invalid rating', t => {
_.times(1000, () => {
let avatar = chance.avatar({ rating: 'invalid' })
t.true(_.isString(avatar))
t.false(avatar.includes('&r='))
})
})
test('avatar() can take and respect a rating', t => {
let ratings = ['g', 'pg', 'r', 'x']
_.times(250, () => {
_.times(ratings.length, (index) => {
let avatar = chance.avatar({ rating: ratings[index] })
t.true(_.isString(avatar))
t.true(avatar.includes('&r=' + ratings[index]))
})
})
})
test('avatar() can take and ignore an invalid fallback image', t => {
_.times(1000, () => {
let avatar = chance.avatar({ fallback: 'invalid' })
t.true(_.isString(avatar))
t.false(avatar.includes('&d='))
})
})
test('avatar() can take just an email', t => {
_.times(1000, () => {
let avatar = chance.avatar('mail@victorquinn.com')
t.true(_.isString(avatar))
t.false(avatar.includes('&d='))
})
})
test('avatar() can take and respect a fallback image', t => {
let fallbacks = [
'404', // Return 404 if not found
'mm', // Mystery man
'identicon', // Geometric pattern based on hash
'monsterid', // A generated monster icon
'wavatar', // A generated face
'retro', // 8-bit icon
'blank' // A transparent png
]
_.times(100, () => {
_.times(fallbacks.length, (index) => {
let avatar = chance.avatar({ fallback: fallbacks[index] })
t.true(_.isString(avatar))
t.true(avatar.includes('&d=' + fallbacks[index]))
})
})
})
// chance.color()
test('color() returns what looks like a hex color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'hex' })
t.true(_.isString(color))
t.is(color.length, 7)
t.true(/#[a-z0-9]+/m.test(color))
})
})
test('color() returns what looks like a gray scale hex color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'hex', grayscale: true })
t.true(_.isString(color))
t.is(color.length, 7)
t.true(/#[a-z0-9]+/m.test(color))
t.is(color.slice(1, 3), color.slice(3, 5))
t.is(color.slice(1, 3), color.slice(5, 7))
})
})
test('color() returns a short hex color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'shorthex' })
t.true(_.isString(color))
t.is(color.length, 4)
t.true(/#[a-z0-9]+/m.test(color))
})
})
test('color() returns what looks like a grayscale short hex color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'shorthex', grayscale: true })
t.true(_.isString(color))
t.is(color.length, 4)
t.is(color.slice(1, 2), color.slice(2, 3))
t.is(color.slice(1, 2), color.slice(3, 4))
})
})
test('color() returns what looks like an rgb color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'rgb' })
t.true(_.isString(color))
let match = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/.exec(color)
t.is(match.length, 4)
t.true(match[1] >= 0)
t.true(match[1] <= 255)
t.true(match[2] >= 0)
t.true(match[2] <= 255)
t.true(match[3] >= 0)
t.true(match[3] <= 255)
})
})
test('color() returns what looks like a grayscale rgb color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'rgb', grayscale: true })
t.true(_.isString(color))
let match = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/.exec(color)
t.is(match.length, 4)
t.true(match[1] >= 0)
t.true(match[1] <= 255)
t.is(match[1], match[2])
t.is(match[1], match[3])
})
})
test('color() returns what looks like an rgba color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'rgba' })
t.true(_.isString(color))
let match = /rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),([01]\.?\d*?)\)/.exec(color)
t.is(match.length, 5)
t.true(match[1] >= 0)
t.true(match[1] <= 255)
t.true(match[2] >= 0)
t.true(match[2] <= 255)
t.true(match[3] >= 0)
t.true(match[3] <= 255)
t.true(match[4] >= 0)
t.true(match[4] <= 255)
})
})
test('color() returns what looks like a grayscale rgba color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'rgba', grayscale: true })
t.true(_.isString(color))
let match = /rgba\((\d{1,3}),(\d{1,3}),(\d{1,3}),([01]\.?\d*?)\)/.exec(color)
t.is(match.length, 5)
t.true(match[1] >= 0)
t.true(match[1] <= 255)
t.true(match[2] >= 0)
t.true(match[2] <= 255)
t.true(match[3] >= 0)
t.true(match[3] <= 255)
t.true(match[4] >= 0)
t.true(match[4] <= 255)
t.is(match[1], match[2])
t.is(match[1], match[3])
t.true(match[4] >= 0)
t.true(match[4] <= 1)
})
})
test('color() 0x color works', t => {
_.times(1000, () => {
let color = chance.color({ format: '0x' })
t.true(_.isString(color))
t.is(color.length, 8)
t.true(/0x[a-z0-9]+/m.test(color))
})
})
test('color() with name returns a valid color name', t => {
_.times(1000, () => {
let color = chance.color({ format: 'name' })
t.true(_.isString(color))
})
})
test('color() upper case returns upper cased color', t => {
_.times(1000, () => {
let color = chance.color({ format: 'hex', casing: 'upper' })
t.true(_.isString(color))
t.is(color.length, 7)
t.is(color.charAt(1).toUpperCase(), color.charAt(1))
t.is(color.charAt(2).toUpperCase(), color.charAt(2))
t.is(color.charAt(3).toUpperCase(), color.charAt(3))
t.is(color.charAt(4).toUpperCase(), color.charAt(4))
t.is(color.charAt(5).toUpperCase(), color.charAt(5))
t.is(color.charAt(6).toUpperCase(), color.charAt(6))
})
})
test('color() bogus format throws error', t => {
const fn = () => chance.color({ format: 'banana' })
t.throws(fn)
})
// chance.domain()
test('domain() returns a domain', t => {
_.times(1000, () => {
let domain = chance.domain()
t.true(_.isString(domain))
t.true(domain.split('.').length > 1)
})
})
test('domain() obeys tld, if specified', t => {
_.times(1000, () => {
let domain = chance.domain({ tld: 'com' })
t.true(_.isString(domain))
t.is(domain.split('.')[1], 'com')
})
})
// chance.email()
test('email() returns what looks like an email', t => {
_.times(1000, () => {
let email = chance.email()
t.true(_.isString(email))
t.true(email.split('@').length > 1)
})
})
test('email() obeys domain, if specified', t => {
_.times(1000, () => {
let email = chance.email({ domain: 'victorquinn.com' })
t.true(_.isString(email))
t.is(email.split('@')[1], 'victorquinn.com')
})
})
test('email() has a leng specified, should generate string before domain with equal length', t => {
_.times(1000, () => {
let email = chance.email({ length: 5 })
t.is(email.split('@')[0].length, 5)
})
})
// chance.fbid()
test('fbid() returns what looks like a Facebook id', t => {
_.times(1000, () => {
let fbid = chance.fbid()
t.true(_.isString(fbid))
t.is(fbid.length, 16)
})
})
// chance.google_analytics()
test('google_analytics() returns what looks like a valid tracking code', t => {
_.times(1000, () => {
let tracking_code = chance.google_analytics()
t.true(_.isString(tracking_code))
t.is(tracking_code.length, 12)
t.true(tracking_code.includes('UA-'))
})
})
// chance.hashtag()
test('hashtag() returns what looks like a hashtag', t => {
_.times(1000, () => {
let hashtag = chance.hashtag()
t.true(_.isString(hashtag))
t.true(/^\#\w+$/m.test(hashtag))
})
})
// chance.ip()
test('ip() returns what looks like an IP address', t => {
_.times(1000, () => {
let ip = chance.ip()
t.true(_.isString(ip))
t.is(ip.split('.').length, 4)
t.true(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/.test(ip))
})
})
// chance.ipv6()
test('ipv6() returns what looks like an IP address (v6)', t => {
_.times(1000, () => {
let ipv6 = chance.ipv6()
t.true(_.isString(ipv6))
t.is(ipv6.split(':').length, 8)
t.true(/[a-f0-9]+:[a-f0-9]+:[a-f0-9]+:[a-f0-9]+:[a-f0-9]+:[a-f0-9]+:[a-f0-9]+:[a-f0-9]+/.test(ipv6))
})
})
// chance.klout()
test('klout() returns what looks like a legit Klout score', t => {
_.times(1000, () => {
let klout = chance.klout()
t.true(_.isNumber(klout))
t.true(klout > 0)
t.true(klout <= 100)
})
})
// chance.locale()
test('locale() should create a valid two character locale with only language', t => {
let locale = chance.locale()
t.true(_.isString(locale))
t.is(locale.length, 2)
})
test('locale() should create a locale with a region code', t => {
let locale = chance.locale({ region: true })
t.true(_.isString(locale))
t.true(locale.split('-').length >= 2)
})
// chance.locales()
test('locales() should return a list of locales', t => {
let locales = chance.locales()
t.true(_.isArray(locales))
t.true(locales.length > 100)
})
test('locales() should return a list of locales', t => {
let locales = chance.locales({ region: true })
t.true(_.isArray(locales))
t.true(locales.length > 100)
})
// chance.md5()
test('md5() should create a hex-encoded MD5 hash of a random ASCII value when passed nothing', t => {
t.is(chance.md5().length, '2063c1608d6e0baf80249c42e2be5804'.length)
})
test('md5() should create a hex-encoded MD5 hash of an ASCII value when passed a string', t => {
t.is(chance.md5('value'), '2063c1608d6e0baf80249c42e2be5804')
})
test('md5() should create a hex-encoded MD5 hash of an ASCII value when passed an object', t => {
t.is(chance.md5({ str: 'value' }), '2063c1608d6e0baf80249c42e2be5804')
})
test('md5() should create a hex-encoded MD5 hash of a UTF-8 value', t => {
t.is(chance.md5('日本'), '4dbed2e657457884e67137d3514119b3')
})
test('md5() should create a hex-encoded HMAC-MD5 hash of an ASCII value and key', t => {
t.is(chance.md5({ str: 'value', key: 'key' }), '01433efd5f16327ea4b31144572c67f6')
})
test('md5() should create a hex-encoded HMAC-MD5 hash of a UTF-8 value and key', t => {
t.is(chance.md5({ str: '日本', key: '日本' }), 'c78b8c7357926981cc04740bd3e9d015')
})
test('md5() should create a raw MD5 hash of an ASCII value', t => {
t.is(chance.md5({ str: 'value', key: null, raw: true }), ' c\xc1`\x8dn\x0b\xaf\x80$\x9cB\xe2\xbeX\x04')
})
test('md5() should create a raw MD5 hash of a UTF-8 value', t => {
t.is(chance.md5({ str: '日本', key: null, raw: true }), 'M\xbe\xd2\xe6WEx\x84\xe6q7\xd3QA\x19\xb3')
})
test('md5() should create a raw HMAC-MD5 hash of an ASCII value', t => {
t.is(chance.md5({ str: 'value', key: 'key', raw: true }), '\x01C>\xfd_\x162~\xa4\xb3\x11DW,g\xf6')
})
test('md5() should create a raw HMAC-MD5 hash of a UTF-8 value', t => {
t.is(chance.md5({ str: '日本', key: '日本', raw: true }), '\xc7\x8b\x8csW\x92i\x81\xcc\x04t\x0b\xd3\xe9\xd0\x15')
})
// chance.port()
test('port() should create a number in the valid port range (0 - 65535)', t => {
_.times(1000, () => {
let port = chance.port()
t.true(_.isNumber(port))
t.true(port >= 0)
t.true(port <= 65535)
})
})
// chance.semver()
test('semver() works as expected', t => {
_.times(1000, () => {
let semver = chance.semver()
t.true(_.isString(semver))
t.true(/[0-9]+\.[0-9]+\.[0-9]+/.test(semver))
})
})
test('semver() accepts a range', t => {
_.times(1000, () => {
let semver = chance.semver({ range: 'banana' })
t.true(_.isString(semver))
t.true(/^banana[0-9]+\.[0-9]+\.[0-9]+/.test(semver))
})
})
test('semver() accepts a prerelease flag', t => {
_.times(1000, () => {
let semver = chance.semver({ range: 'banana' })
t.true(_.isString(semver))
t.true(/[0-9]+\.[0-9]+\.[0-9]+-?[dev|beta|alpha]?/.test(semver))
})
})
// chance.tld()
test('tld() returns a tld', t => {
_.times(1000, () => {
let tld = chance.tld()
t.true(_.isString(tld))
t.true(tld.length < 6)
})
})
// chance.twitter()
test('twitter() returns what looks like a Twitter handle', t => {
_.times(1000, () => {
let twitter = chance.twitter()
t.true(_.isString(twitter))
t.true(/\@[A-Za-z]+/m.test(twitter))
})
})
// chance.url()
test('url() deal with url', t => {
_.times(1000, () => {
let url = chance.url()
t.true(_.isString(url))
t.true(url.split('.').length > 1)
t.true(url.split('://').length > 1)
})
})
test('url() can take and respect a domain', t => {
_.times(1000, () => {
let url = chance.url({ domain: 'victorquinn.com' })
t.true(_.isString(url))
t.true(url.split('.').length > 1)
t.true(url.split('://').length > 1)
t.true(url.split('victorquinn.com').length > 1)
})
})
test('url() can take and respect a domain prefix', t => {
_.times(1000, () => {
let url = chance.url({ domain_prefix: 'www' })
t.true(_.isString(url))
t.true(url.split('.').length > 1)
t.true(url.split('://').length > 1)
t.true(url.split('www').length > 1)
})
})
test('url() can take and respect a path', t => {
_.times(1000, () => {
let url = chance.url({ path: 'images' })
t.true(_.isString(url))
t.true(url.split('.').length > 1)
t.true(url.split('://').length > 1)
t.true(url.split('/images').length > 1)
})
})
test('url() can take and respect extensions', t => {
_.times(1000, () => {
let url = chance.url({ extensions: ['html'] })
t.true(_.isString(url))
t.true(url.split('.').length > 1)
t.true(url.split('://').length > 1)
t.not(url.indexOf('.html'), -1)
})
})
// chance.loremPicsum()
test('loremPicsum() returns loremPicsum url with default width and height', t => {
_.times(1000, () => {
let loremPicsumUrl = chance.loremPicsum()
t.true(_.isString(loremPicsumUrl))
t.true(loremPicsumUrl.split('.').length > 1)
t.true(loremPicsumUrl.split('://').length > 1)
t.true(loremPicsumUrl.split('picsum.photos').length > 1)
t.true(loremPicsumUrl.split('/500/500').length > 1)
t.true(loremPicsumUrl.split('/?random').length > 1)
})
})
test('loremPicsum() returns loremPicsum url that respects width and height', t => {
_.times(1000, () => {
let width = chance.natural();
let height = chance.natural();
let loremPicsumUrl = chance.loremPicsum({
width,
height
})
t.true(_.isString(loremPicsumUrl))
t.true(loremPicsumUrl.split('.').length > 1)
t.true(loremPicsumUrl.split('://').length > 1)
t.true(loremPicsumUrl.split('picsum.photos').length > 1)
t.true(loremPicsumUrl.split('/' + width + '/' + height).length > 1)
t.true(loremPicsumUrl.split('/?random').length > 1)
})
})
test('loremPicsum() returns loremPicsum url that respects greyscale', t => {
_.times(1000, () => {
let loremPicsumUrl = chance.loremPicsum({
greyscale: true
})
t.true(_.isString(loremPicsumUrl))
t.true(loremPicsumUrl.split('.').length > 1)
t.true(loremPicsumUrl.split('://').length > 1)
t.true(loremPicsumUrl.split('picsum.photos').length > 1)
t.true(loremPicsumUrl.split('/g/500/500').length > 1)
t.true(loremPicsumUrl.split('/?random').length > 1)
})
})
test('loremPicsum() returns loremPicsum url that respects blurred', t => {
_.times(1000, () => {
let loremPicsumUrl = chance.loremPicsum({
blurred: true
})
t.true(_.isString(loremPicsumUrl))
t.true(loremPicsumUrl.split('.').length > 1)
t.true(loremPicsumUrl.split('://').length > 1)
t.true(loremPicsumUrl.split('picsum.photos').length > 1)
t.true(loremPicsumUrl.split('/500/500').length > 1)
t.true(loremPicsumUrl.split('/?blur').length > 1)
})
})