summaryrefslogtreecommitdiff
path: root/src/node_modules/chance/test
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2021-12-21 16:52:28 +0100
committerMinteck <contact@minteck.org>2021-12-21 16:52:28 +0100
commit46e43f4bde4a35785b4997b81e86cd19f046b69b (patch)
treec53c2f826f777f9d6b2d249dab556feb72a6c3a6 /src/node_modules/chance/test
downloadlangdetect-46e43f4bde4a35785b4997b81e86cd19f046b69b.tar.gz
langdetect-46e43f4bde4a35785b4997b81e86cd19f046b69b.tar.bz2
langdetect-46e43f4bde4a35785b4997b81e86cd19f046b69b.zip
Commit
Diffstat (limited to 'src/node_modules/chance/test')
-rw-r--r--src/node_modules/chance/test/helpers/phoneNumber.min.js6
-rw-r--r--src/node_modules/chance/test/test.address.js740
-rw-r--r--src/node_modules/chance/test/test.animal.js40
-rw-r--r--src/node_modules/chance/test/test.basic.js560
-rw-r--r--src/node_modules/chance/test/test.buffer.js31
-rw-r--r--src/node_modules/chance/test/test.company.js15
-rw-r--r--src/node_modules/chance/test/test.file.js116
-rw-r--r--src/node_modules/chance/test/test.finance.js220
-rw-r--r--src/node_modules/chance/test/test.helpers.js433
-rw-r--r--src/node_modules/chance/test/test.misc.js298
-rw-r--r--src/node_modules/chance/test/test.mobile.js29
-rw-r--r--src/node_modules/chance/test/test.music.js52
-rw-r--r--src/node_modules/chance/test/test.normal.js114
-rw-r--r--src/node_modules/chance/test/test.person.js447
-rw-r--r--src/node_modules/chance/test/test.regional.js116
-rw-r--r--src/node_modules/chance/test/test.text.js123
-rw-r--r--src/node_modules/chance/test/test.time.js299
-rw-r--r--src/node_modules/chance/test/test.web.js597
18 files changed, 4236 insertions, 0 deletions
diff --git a/src/node_modules/chance/test/helpers/phoneNumber.min.js b/src/node_modules/chance/test/helpers/phoneNumber.min.js
new file mode 100644
index 0000000..be03356
--- /dev/null
+++ b/src/node_modules/chance/test/helpers/phoneNumber.min.js
@@ -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); \ No newline at end of file
diff --git a/src/node_modules/chance/test/test.address.js b/src/node_modules/chance/test/test.address.js
new file mode 100644
index 0000000..7e65c61
--- /dev/null
+++ b/src/node_modules/chance/test/test.address.js
@@ -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))
+ })
+})
diff --git a/src/node_modules/chance/test/test.animal.js b/src/node_modules/chance/test/test.animal.js
new file mode 100644
index 0000000..7ad45e6
--- /dev/null
+++ b/src/node_modules/chance/test/test.animal.js
@@ -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.")
+ })
+})
diff --git a/src/node_modules/chance/test/test.basic.js b/src/node_modules/chance/test/test.basic.js
new file mode 100644
index 0000000..c7f1069
--- /dev/null
+++ b/src/node_modules/chance/test/test.basic.js
@@ -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')
+})
diff --git a/src/node_modules/chance/test/test.buffer.js b/src/node_modules/chance/test/test.buffer.js
new file mode 100644
index 0000000..04b7802
--- /dev/null
+++ b/src/node_modules/chance/test/test.buffer.js
@@ -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.");
+});
diff --git a/src/node_modules/chance/test/test.company.js b/src/node_modules/chance/test/test.company.js
new file mode 100644
index 0000000..ab88a5f
--- /dev/null
+++ b/src/node_modules/chance/test/test.company.js
@@ -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)
+ })
+})
+
diff --git a/src/node_modules/chance/test/test.file.js b/src/node_modules/chance/test/test.file.js
new file mode 100644
index 0000000..4b0bf61
--- /dev/null
+++ b/src/node_modules/chance/test/test.file.js
@@ -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)
+ })
+})
diff --git a/src/node_modules/chance/test/test.finance.js b/src/node_modules/chance/test/test.finance.js
new file mode 100644
index 0000000..0b6e20a
--- /dev/null
+++ b/src/node_modules/chance/test/test.finance.js
@@ -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))
+})
diff --git a/src/node_modules/chance/test/test.helpers.js b/src/node_modules/chance/test/test.helpers.js
new file mode 100644
index 0000000..171bcc2
--- /dev/null
+++ b/src/node_modules/chance/test/test.helpers.js
@@ -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)
+ })
+})
diff --git a/src/node_modules/chance/test/test.misc.js b/src/node_modules/chance/test/test.misc.js
new file mode 100644
index 0000000..9ec3748
--- /dev/null
+++ b/src/node_modules/chance/test/test.misc.js
@@ -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))
+ })
+})
diff --git a/src/node_modules/chance/test/test.mobile.js b/src/node_modules/chance/test/test.mobile.js
new file mode 100644
index 0000000..5361d80
--- /dev/null
+++ b/src/node_modules/chance/test/test.mobile.js
@@ -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())))
+})
diff --git a/src/node_modules/chance/test/test.music.js b/src/node_modules/chance/test/test.music.js
new file mode 100644
index 0000000..2910796
--- /dev/null
+++ b/src/node_modules/chance/test/test.music.js
@@ -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)
+ })
+}) \ No newline at end of file
diff --git a/src/node_modules/chance/test/test.normal.js b/src/node_modules/chance/test/test.normal.js
new file mode 100644
index 0000000..14b37d2
--- /dev/null
+++ b/src/node_modules/chance/test/test.normal.js
@@ -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'])
+})
diff --git a/src/node_modules/chance/test/test.person.js b/src/node_modules/chance/test/test.person.js
new file mode 100644
index 0000000..0408bc9
--- /dev/null
+++ b/src/node_modules/chance/test/test.person.js
@@ -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)))
+})
diff --git a/src/node_modules/chance/test/test.regional.js b/src/node_modules/chance/test/test.regional.js
new file mode 100644
index 0000000..2fd7aee
--- /dev/null
+++ b/src/node_modules/chance/test/test.regional.js
@@ -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))
+ })
+})
diff --git a/src/node_modules/chance/test/test.text.js b/src/node_modules/chance/test/test.text.js
new file mode 100644
index 0000000..0bbd644
--- /dev/null
+++ b/src/node_modules/chance/test/test.text.js
@@ -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);
+ })
+})
diff --git a/src/node_modules/chance/test/test.time.js b/src/node_modules/chance/test/test.time.js
new file mode 100644
index 0000000..cead8dc
--- /dev/null
+++ b/src/node_modules/chance/test/test.time.js
@@ -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)
+ })
+})
diff --git a/src/node_modules/chance/test/test.web.js b/src/node_modules/chance/test/test.web.js
new file mode 100644
index 0000000..63e5b62
--- /dev/null
+++ b/src/node_modules/chance/test/test.web.js
@@ -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)
+ })
+})