From 46e43f4bde4a35785b4997b81e86cd19f046b69b Mon Sep 17 00:00:00 2001 From: Minteck Date: Tue, 21 Dec 2021 16:52:28 +0100 Subject: Commit --- .../chance/test/helpers/phoneNumber.min.js | 6 + src/node_modules/chance/test/test.address.js | 740 +++++++++++++++++++++ src/node_modules/chance/test/test.animal.js | 40 ++ src/node_modules/chance/test/test.basic.js | 560 ++++++++++++++++ src/node_modules/chance/test/test.buffer.js | 31 + src/node_modules/chance/test/test.company.js | 15 + src/node_modules/chance/test/test.file.js | 116 ++++ src/node_modules/chance/test/test.finance.js | 220 ++++++ src/node_modules/chance/test/test.helpers.js | 433 ++++++++++++ src/node_modules/chance/test/test.misc.js | 298 +++++++++ src/node_modules/chance/test/test.mobile.js | 29 + src/node_modules/chance/test/test.music.js | 52 ++ src/node_modules/chance/test/test.normal.js | 114 ++++ src/node_modules/chance/test/test.person.js | 447 +++++++++++++ src/node_modules/chance/test/test.regional.js | 116 ++++ src/node_modules/chance/test/test.text.js | 123 ++++ src/node_modules/chance/test/test.time.js | 299 +++++++++ src/node_modules/chance/test/test.web.js | 597 +++++++++++++++++ 18 files changed, 4236 insertions(+) create mode 100644 src/node_modules/chance/test/helpers/phoneNumber.min.js create mode 100644 src/node_modules/chance/test/test.address.js create mode 100644 src/node_modules/chance/test/test.animal.js create mode 100644 src/node_modules/chance/test/test.basic.js create mode 100644 src/node_modules/chance/test/test.buffer.js create mode 100644 src/node_modules/chance/test/test.company.js create mode 100644 src/node_modules/chance/test/test.file.js create mode 100644 src/node_modules/chance/test/test.finance.js create mode 100644 src/node_modules/chance/test/test.helpers.js create mode 100644 src/node_modules/chance/test/test.misc.js create mode 100644 src/node_modules/chance/test/test.mobile.js create mode 100644 src/node_modules/chance/test/test.music.js create mode 100644 src/node_modules/chance/test/test.normal.js create mode 100644 src/node_modules/chance/test/test.person.js create mode 100644 src/node_modules/chance/test/test.regional.js create mode 100644 src/node_modules/chance/test/test.text.js create mode 100644 src/node_modules/chance/test/test.time.js create mode 100644 src/node_modules/chance/test/test.web.js (limited to 'src/node_modules/chance/test') 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 { + 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 { + let mrz = chance.mrz() + t.true(_.isString(mrz)) + t.is(mrz.substr(0, 5), 'P { + _.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) + }) +}) -- cgit