From 4cdbfcf37dea4987083a230e796ef53c175e7872 Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Sat, 13 May 2017 14:50:56 +0100 Subject: [PATCH 01/21] Added documentation. --- README.md | 1 + doc/internet.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 doc/internet.md diff --git a/README.md b/README.md index c530ea9..d3755fd 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Contents - [Faker.Hacker](doc/hacker.md) - [Faker.HarryPotter](doc/harry_potter.md) - [Faker.Hipster](doc/hipster.md) + - [Faker.Internet](doc/internet.md) - [Faker.LordOfTheRings](doc/lord_of_the_rings.md) - [Faker.Lorem](doc/lorem.md) - [Faker.LoremFlickr](doc/lorem_flickr.md) diff --git a/doc/internet.md b/doc/internet.md new file mode 100644 index 0000000..b47450c --- /dev/null +++ b/doc/internet.md @@ -0,0 +1,75 @@ +# Faker.Internet + +```js +// Optional argument name=nil +Faker.Internet.email() //=> "eliza@mann.net" + +Faker.Internet.email('Nancy') //=> "nancy@terry.biz" + +// Optional argument name=nil +Faker.Internet.freeEmail() //=> "freddy@gmail.com" + +Faker.Internet.freeEmail('Nancy') //=> "nancy@yahoo.com" + +// Optional argument name=nil +Faker.Internet.safeEmail() //=> "christelle@example.org" + +Faker.Internet.safeEmail('Nancy') //=> "nancy@example.net" + +// Optional arguments specifier=nil, separators=%w(. _) +Faker.Internet.userName() //=> "alexie" + +Faker.Internet.userName('Nancy') //=> "nancy" + +Faker.Internet.userName('Nancy Johnson', %w(. _ -)) //=> "johnson-nancy" + +// Optional arguments: min_length=5, max_length=8 +Faker.Internet.userName(5..8) + +// Optional arguments: min_length=8, max_length=16 +Faker.Internet.password() //=> "vg5msvy1uerg7" + +Faker.Internet.password(8) //=> "yfgjik0hgzdqs0" + +Faker.Internet.password(10, 20) //=> "eoc9shwd1hwq4vbgfw" + +Faker.Internet.password(10, 20, true) //=> "3k5qS15aNmG" + +Faker.Internet.password(10, 20, true, true) //=> "*%NkOnJsH4" + +Faker.Internet.domainName() //=> "effertz.info" + +Faker.Internet.fixUmlauts('äöüß') //=> "aeoeuess" + +Faker.Internet.domainWord() //=> "haleyziemann" + +Faker.Internet.domainSuffix() //=> "info" + +Faker.Internet.ipV4Address() //=> "24.29.18.175" + +// Private IP range according to RFC 1918 and 127.0.0.0/8 and 169.254.0.0/16. +Faker.Internet.privateIPV4Address() //=> "10.0.0.1" + +// Guaranteed not to be in the ip range from the private_ip_v4_address method. +Faker.Internet.publicIPV4Address() //=> "24.29.18.175" + +Faker.Internet.ipV4Cidr() //=> "24.29.18.175/21" + +Faker.Internet.ipV6Address() //=> "ac5f:d696:3807:1d72:2eb5:4e81:7d2b:e1df" + +Faker.Internet.ipV6Cidr() //=> "ac5f:d696:3807:1d72:2eb5:4e81:7d2b:e1df/78" + +// Optional argument prefix='' +Faker.Internet.macAddress() //=> "e6:0d:00:11:ed:4f" +Faker.Internet.macAddress('55:44:33') //=> "55:44:33:02:1d:9b" + +// Optional arguments: host=domain_name, path="/#{user_name}" +Faker.Internet.url() //=> "http://thiel.com/chauncey_simonis" +Faker.Internet.url('example.com') //=> "http://example.com/clotilde.swift" +Faker.Internet.url('example.com', '/foobar.html') //=> "http://example.com/foobar.html" + +// Optional arguments: words=nil, glue=nil +Faker.Internet.slug() //=> "pariatur_laudantium" +Faker.Internet.slug('foo bar') //=> "foo.bar" +Faker.Internet.slug('foo bar', '-') //=> "foo-bar" +``` From 7cbf4cf5e4e710aaa733d81d81ec3383edc7780c Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Sat, 13 May 2017 14:51:15 +0100 Subject: [PATCH 02/21] Added data. --- data/internet.json | 17 ++++ src/faker/internet.js | 82 ++++++++++++++++++++ test/faker/internet.spec.js | 150 ++++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 data/internet.json create mode 100644 src/faker/internet.js create mode 100644 test/faker/internet.spec.js diff --git a/data/internet.json b/data/internet.json new file mode 100644 index 0000000..8b6f70f --- /dev/null +++ b/data/internet.json @@ -0,0 +1,17 @@ +{ + "freeEmails": [ + "gmail.com", + "yahoo.com", + "hotmail.com" + ], + "domainSuffixes": [ + "com", + "biz", + "info", + "name", + "net", + "org", + "io", + "co" + ] +} diff --git a/src/faker/internet.js b/src/faker/internet.js new file mode 100644 index 0000000..9ac7809 --- /dev/null +++ b/src/faker/internet.js @@ -0,0 +1,82 @@ +import { itemFromCollection, randomNumber } from '../utils/random'; + +const data = require('../../data/internet.json'); + +// 0-9, a-z +const CHARACTERS = [...Array(10).keys()].concat([...Array(26).keys()].map(i => String.fromCharCode(97+i))); +const SYMBOLS = ['!', '@', '#', '$', '%', '^', '&', '*']; + +export function email(name=null) { + return [ + userName(name), + domainName() + ].join('@'); +} + +export function freeEmail(name=null) { + return [ + userName(name), + itemFromCollection(data['freeEmails']) + ].join('@'); +} + +export function safeEmail(name=null) { + return [ + userName(name), + `example.${itemFromCollection(['org', 'com', 'net'])}` + ].join('@'); +} + +export function userName() { + return itemFromCollection(data['userNames']); +} + +export function password(minLength=8, maxLength=16, mixCase=true, specialChars=false) { + const diffLength = maxLength - minLength; + const extraCharacters = randomNumber(0, diffLength + 1); + const chars = specialChars ? [...CHARACTERS, ...SYMBOLS] : CHARACTERS; + + return [...Array(minLength + extraCharacters).keys()].map((_, index) => { + const c = itemFromCollection(chars); + return mixCase && index % 2 == 0 ? c.toUpperCase() : c; + }).join(''); +} + +export function domainName() { +} + +export function fixUmlauts() { +} + +export function domainWord() { +} + +export function domainSuffix() { +} + +export function ipV4Address() { +} + +export function privateIPV4Address() { +} + +export function publicIPV4Address() { +} + +export function ipV4Cidr() { +} + +export function ipV6Address() { +} + +export function ipV6Cidr() { +} + +export function macAddress() { +} + +export function url() { +} + +export function slug() { +} diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js new file mode 100644 index 0000000..1ba7054 --- /dev/null +++ b/test/faker/internet.spec.js @@ -0,0 +1,150 @@ +'use strict'; +const expect = require('chai').expect; +const Internet = require('../../src/faker/internet'); +const data = require('../../data/internet.json'); + +describe('Internet', () => { + describe('#email', () => { + it('should return a email', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.email()).to.be.oneOf(data['emails']); + }); + }); + }); + + describe('#freeEmail', () => { + it('should return a freeEmail', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.freeEmail()).to.be.oneOf(data['freeEmails']); + }); + }); + }); + + describe('#safeEmail', () => { + it('should return a safeEmail', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.safeEmail()).to.be.oneOf(data['safeEmails']); + }); + }); + }); + + describe('#userName', () => { + it('should return a userName', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.userName()).to.be.oneOf(data['userNames']); + }); + }); + }); + + describe('#password', () => { + it('should return a password', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.password()).to.equal(''); + }); + }); + }); + + describe('#domainName', () => { + it('should return a domainName', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.domainName()).to.be.oneOf(data['domainNames']); + }); + }); + }); + + describe('#fixUmlauts', () => { + it('should return a fixUmlauts', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.fixUmlauts()).to.be.oneOf(data['fixUmlauts']); + }); + }); + }); + + describe('#domainWord', () => { + it('should return a domainWord', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.domainWord()).to.be.oneOf(data['domainWords']); + }); + }); + }); + + describe('#domainSuffix', () => { + it('should return a domainSuffix', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.domainSuffix()).to.be.oneOf(data['domainSuffixes']); + }); + }); + }); + + describe('#ipV4_address', () => { + it('should return a ipV4_address', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.ipV4_address()).to.be.oneOf(data['ipV4_addresses']); + }); + }); + }); + + describe('#privateIpV4_address', () => { + it('should return a privateIpV4_address', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.privateIpV4_address()).to.be.oneOf(data['privateIpV4_addresses']); + }); + }); + }); + + describe('#publicIpV4_address', () => { + it('should return a publicIpV4_address', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.publicIpV4_address()).to.be.oneOf(data['publicIpV4_addresses']); + }); + }); + }); + + describe('#ipV4_cidr', () => { + it('should return a ipV4_cidr', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.ipV4_cidr()).to.be.oneOf(data['ipV4_cidrs']); + }); + }); + }); + + describe('#ipV6_address', () => { + it('should return a ipV6_address', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.ipV6_address()).to.be.oneOf(data['ipV6_addresses']); + }); + }); + }); + + describe('#ipV6_cidr', () => { + it('should return a ipV6_cidr', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.ipV6_cidr()).to.be.oneOf(data['ipV6_cidrs']); + }); + }); + }); + + describe('#macAddress', () => { + it('should return a macAddress', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.macAddress()).to.be.oneOf(data['macAddresses']); + }); + }); + }); + + describe('#url', () => { + it('should return a url', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.url()).to.be.oneOf(data['urls']); + }); + }); + }); + + describe('#slug', () => { + it('should return a slug', () => { + [...Array(100).keys()].forEach(_ => { + // expect(Internet.slug()).to.be.oneOf(data['slugs']); + }); + }); + }); +}); From 0288057b5eaa2357d5df924d8e546ac46aae54e0 Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Mon, 3 Jul 2017 21:42:52 +0100 Subject: [PATCH 03/21] Implemented the domainName, domainWord and domainSuffix methods with tests. --- src/faker/internet.js | 7 +++++++ test/faker/internet.spec.js | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 9ac7809..4aa14c1 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -1,6 +1,7 @@ import { itemFromCollection, randomNumber } from '../utils/random'; const data = require('../../data/internet.json'); +const nameData = require('../../data/name.json'); // 0-9, a-z const CHARACTERS = [...Array(10).keys()].concat([...Array(26).keys()].map(i => String.fromCharCode(97+i))); @@ -43,15 +44,21 @@ export function password(minLength=8, maxLength=16, mixCase=true, specialChars=f } export function domainName() { + return [ + domainWord(), + domainSuffix() + ].join('.'); } export function fixUmlauts() { } export function domainWord() { + return itemFromCollection(nameData['lastNames']); } export function domainSuffix() { + return itemFromCollection(data['domainSuffixes']) } export function ipV4Address() { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 1ba7054..799e868 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -2,6 +2,7 @@ const expect = require('chai').expect; const Internet = require('../../src/faker/internet'); const data = require('../../data/internet.json'); +const nameData = require('../../data/name.json'); describe('Internet', () => { describe('#email', () => { @@ -47,7 +48,9 @@ describe('Internet', () => { describe('#domainName', () => { it('should return a domainName', () => { [...Array(100).keys()].forEach(_ => { - // expect(Internet.domainName()).to.be.oneOf(data['domainNames']); + const domainName = Internet.domainName(); + expect(domainName.split('.')[0]).to.be.oneOf(nameData['lastNames']); + expect(domainName.split('.')[1]).to.be.oneOf(data['domainSuffixes']); }); }); }); @@ -63,7 +66,7 @@ describe('Internet', () => { describe('#domainWord', () => { it('should return a domainWord', () => { [...Array(100).keys()].forEach(_ => { - // expect(Internet.domainWord()).to.be.oneOf(data['domainWords']); + expect(Internet.domainWord()).to.be.oneOf(nameData['lastNames']); }); }); }); @@ -71,7 +74,7 @@ describe('Internet', () => { describe('#domainSuffix', () => { it('should return a domainSuffix', () => { [...Array(100).keys()].forEach(_ => { - // expect(Internet.domainSuffix()).to.be.oneOf(data['domainSuffixes']); + expect(Internet.domainSuffix()).to.be.oneOf(data['domainSuffixes']); }); }); }); From 9ee0200ee3f0b35a4e5937144cc829a474c18579 Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Wed, 5 Jul 2017 23:14:22 +0100 Subject: [PATCH 04/21] Using reduce to create password. --- src/faker/internet.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 4aa14c1..a0a9607 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -37,10 +37,10 @@ export function password(minLength=8, maxLength=16, mixCase=true, specialChars=f const extraCharacters = randomNumber(0, diffLength + 1); const chars = specialChars ? [...CHARACTERS, ...SYMBOLS] : CHARACTERS; - return [...Array(minLength + extraCharacters).keys()].map((_, index) => { - const c = itemFromCollection(chars); - return mixCase && index % 2 == 0 ? c.toUpperCase() : c; - }).join(''); + return [...Array(minLength + extraCharacters).keys()].reduce((result, val, index) => { + const c = itemFromCollection(chars).toString(); + return result + (mixCase && index % 2 == 0 ? c.toUpperCase() : c); + }, ''); } export function domainName() { From 3686b00acdc8f7eb963968a880fd9600c9156191 Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Wed, 5 Jul 2017 23:14:35 +0100 Subject: [PATCH 05/21] Added extra tests for the password function. --- test/faker/internet.spec.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 799e868..3e26711 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -40,7 +40,25 @@ describe('Internet', () => { describe('#password', () => { it('should return a password', () => { [...Array(100).keys()].forEach(_ => { - expect(Internet.password()).to.equal(''); + expect(Internet.password()).to.match(/^[a-zA-Z0-9]+$/); + }); + }); + + it('should return a password between 8 and 16 alphanumeric characters by default', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.password()).to.match(/^[a-zA-Z0-9]{8,16}$/); + }); + }); + + it('should return a lowercase password when mixCase is false', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.password(8, 16, false)).to.match(/^[a-z0-9]+$/); + }); + }); + + it('should return a password with special characters when specialChars is true', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.password(8, 16, true, true)).to.match(/[\!\@\#\$\%\^\&\*]/); }); }); }); From f3dcdcbe313b0be13bbff25f4501ca63fcce43fd Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Thu, 6 Jul 2017 23:19:10 +0100 Subject: [PATCH 06/21] Made sure we have a long password that will have special characters in it. --- test/faker/internet.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 3e26711..dc50867 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -58,7 +58,7 @@ describe('Internet', () => { it('should return a password with special characters when specialChars is true', () => { [...Array(100).keys()].forEach(_ => { - expect(Internet.password(8, 16, true, true)).to.match(/[\!\@\#\$\%\^\&\*]/); + expect(Internet.password(128, 128, true, true)).to.match(/[\!\@\#\$\%\^\&\*]/); }); }); }); From 64169c68568a8f9c1b4d3da5c5cd32a6b1765327 Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Thu, 6 Jul 2017 23:25:57 +0100 Subject: [PATCH 07/21] Using latest version of chai-datetime. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c29c7e5..31fc61c 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "babel-eslint": "^7.2.1", "babel-preset-es2015": "^6.24.0", "chai": "^4.0.2", - "chai-datetime": "github:mrstebo/chai-datetime#feature/date-within", + "chai-datetime": "^1.5.0", "eslint": "^4.1.0", "eslint-config-es2015": "^1.1.0", "gulp": "^3.9.1", From b167b53045742ded06a90b72d1cd2bd1d1bee27e Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Thu, 6 Jul 2017 23:26:15 +0100 Subject: [PATCH 08/21] Implemented the fixUmlauts function. --- src/faker/internet.js | 6 +++++- test/faker/internet.spec.js | 14 ++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index a0a9607..2de1e29 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -50,7 +50,11 @@ export function domainName() { ].join('.'); } -export function fixUmlauts() { +export function fixUmlauts(value='') { + return value + .replace(/ä/g, 'ae') + .replace(/ö/g, 'oe') + .replace(/ü/g, 'ue'); } export function domainWord() { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index dc50867..7cc3017 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -74,10 +74,16 @@ describe('Internet', () => { }); describe('#fixUmlauts', () => { - it('should return a fixUmlauts', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.fixUmlauts()).to.be.oneOf(data['fixUmlauts']); - }); + it('should replace ä with ae', () => { + expect(Internet.fixUmlauts('ä')).to.eql('ae'); + }); + + it('should replace ö with oe', () => { + expect(Internet.fixUmlauts('ö')).to.eql('oe'); + }); + + it('should replace ü with ue', () => { + expect(Internet.fixUmlauts('ü')).to.eql('ue'); }); }); From 75b48e670f59bff32d072959964d228b4c591feb Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Thu, 6 Jul 2017 23:27:09 +0100 Subject: [PATCH 09/21] Cleaned up tests that have not been implemented yet. --- test/faker/internet.spec.js | 65 ------------------------------------- 1 file changed, 65 deletions(-) diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 7cc3017..ae18a05 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -6,35 +6,15 @@ const nameData = require('../../data/name.json'); describe('Internet', () => { describe('#email', () => { - it('should return a email', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.email()).to.be.oneOf(data['emails']); - }); - }); }); describe('#freeEmail', () => { - it('should return a freeEmail', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.freeEmail()).to.be.oneOf(data['freeEmails']); - }); - }); }); describe('#safeEmail', () => { - it('should return a safeEmail', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.safeEmail()).to.be.oneOf(data['safeEmails']); - }); - }); }); describe('#userName', () => { - it('should return a userName', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.userName()).to.be.oneOf(data['userNames']); - }); - }); }); describe('#password', () => { @@ -104,74 +84,29 @@ describe('Internet', () => { }); describe('#ipV4_address', () => { - it('should return a ipV4_address', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.ipV4_address()).to.be.oneOf(data['ipV4_addresses']); - }); - }); }); describe('#privateIpV4_address', () => { - it('should return a privateIpV4_address', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.privateIpV4_address()).to.be.oneOf(data['privateIpV4_addresses']); - }); - }); }); describe('#publicIpV4_address', () => { - it('should return a publicIpV4_address', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.publicIpV4_address()).to.be.oneOf(data['publicIpV4_addresses']); - }); - }); }); describe('#ipV4_cidr', () => { - it('should return a ipV4_cidr', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.ipV4_cidr()).to.be.oneOf(data['ipV4_cidrs']); - }); - }); }); describe('#ipV6_address', () => { - it('should return a ipV6_address', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.ipV6_address()).to.be.oneOf(data['ipV6_addresses']); - }); - }); }); describe('#ipV6_cidr', () => { - it('should return a ipV6_cidr', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.ipV6_cidr()).to.be.oneOf(data['ipV6_cidrs']); - }); - }); }); describe('#macAddress', () => { - it('should return a macAddress', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.macAddress()).to.be.oneOf(data['macAddresses']); - }); - }); }); describe('#url', () => { - it('should return a url', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.url()).to.be.oneOf(data['urls']); - }); - }); }); describe('#slug', () => { - it('should return a slug', () => { - [...Array(100).keys()].forEach(_ => { - // expect(Internet.slug()).to.be.oneOf(data['slugs']); - }); - }); }); }); From efc9a002b90c7a87f76f51e12f8144132ad786a3 Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Fri, 7 Jul 2017 09:32:02 +0100 Subject: [PATCH 10/21] Added the watch script. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 31fc61c..a4b1d55 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "version:patch": "npm version patch", "prepublish": "./node_modules/.bin/gulp build", - "test": "./node_modules/.bin/gulp test coveralls" + "test": "./node_modules/.bin/gulp test coveralls", + "watch": "./node_modules/.bin/gulp watch" }, "repository": { "type": "git", From a64efe358a0272c3e1d1cfb7aaeeb3e18e0d49dc Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Fri, 7 Jul 2017 09:32:21 +0100 Subject: [PATCH 11/21] Removed the error handler (was causing travis to pass even if we had a failed test). --- Gulpfile.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index b9f9c88..fdd299c 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -40,12 +40,8 @@ gulp.task('test', ['istanbul'], () => { colors: true, harmony: true })) - .on('error', function(err) { - gutil.log(gutil.colors.red(err)); - this.emit('end'); - }) - .pipe(istanbul.writeReports()) .pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } })); + // .pipe(istanbul.writeReports()) }); gulp.task('coveralls', ['istanbul', 'test'], () => { From 7605cd5a305005cdca9865aa3230ed555aa9dbed Mon Sep 17 00:00:00 2001 From: Steven Atkinson Date: Fri, 7 Jul 2017 09:57:47 +0100 Subject: [PATCH 12/21] Implemented the macAddress function. --- src/faker/internet.js | 5 ++++- test/faker/internet.spec.js | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 2de1e29..351b8b7 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -83,7 +83,10 @@ export function ipV6Address() { export function ipV6Cidr() { } -export function macAddress() { +export function macAddress(prefix='') { + const prefixDigits = prefix.split(':').filter(x => x).map(x => parseInt(x, 16)); + const addressDigits = [...Array(6 - prefixDigits.length).keys()].map(x => randomNumber(0, 255)); + return [...prefixDigits, ...addressDigits].map(x => x.toString(16)).join(':'); } export function url() { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index ae18a05..4d3e48e 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -102,6 +102,17 @@ describe('Internet', () => { }); describe('#macAddress', () => { + it('should return a colon separated address', () => { + expect(Internet.macAddress()).to.match(/\:/); + }); + + it('should contain no more than 6 separated values', () => { + expect(Internet.macAddress().split(':')).to.have.lengthOf(6); + }); + + it('should have values that do not exceed 0xFF', () => { + expect(Internet.macAddress().split(':').map(x => parseInt(x, 16)).sort((a, b) => a < b)[0]).to.be.below(0xFF); + }); }); describe('#url', () => { From ab56f670e1b8f65337955cf430ad1ed7cc1985b2 Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 9 Jul 2017 11:05:25 +0100 Subject: [PATCH 13/21] Added the .gitattributes file. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto From 0cfe9ddfc83269690aa4c34147c2b9dbd07ba85d Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 9 Jul 2017 11:26:10 +0100 Subject: [PATCH 14/21] Implemented the slug method with tests. --- src/faker/internet.js | 6 +++++- test/faker/internet.spec.js | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 351b8b7..6617282 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -2,6 +2,7 @@ import { itemFromCollection, randomNumber } from '../utils/random'; const data = require('../../data/internet.json'); const nameData = require('../../data/name.json'); +const loremData = require('../../data/lorem.json'); // 0-9, a-z const CHARACTERS = [...Array(10).keys()].concat([...Array(26).keys()].map(i => String.fromCharCode(97+i))); @@ -92,5 +93,8 @@ export function macAddress(prefix='') { export function url() { } -export function slug() { +export function slug(words='', glue='') { + return (words || [...Array(2).keys()].map(_ => itemFromCollection(loremData['words'])).join(' ')) + .replace(/\s+/g, glue || itemFromCollection(['-', '_', '.'])) + .toLowerCase(); } diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 4d3e48e..b0f47c9 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -119,5 +119,20 @@ describe('Internet', () => { }); describe('#slug', () => { + it('should return a slug when no parameters are specified', () => { + expect(Internet.slug()).to.match(/^\w+(\-|\_|\.)\w+$/); + }); + + it('should return slug with specified words', () => { + expect(Internet.slug('test slug')).to.match(/^test(\-|\_|\.)slug$/); + }); + + it('should return slug joined with the specified "glue"', () => { + expect(Internet.slug(null, '#')).to.match(/^\w+\#\w+$/); + }); + + it('should be all lowercase', () => { + expect(Internet.slug()).to.match(/^[a-z]+.[a-z]+$/) + }); }); }); From 31c879351236cf6cb2c9ce3506aacc0b2b77b186 Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 9 Jul 2017 22:49:40 +0100 Subject: [PATCH 15/21] Added the ability to shuffle an array. --- src/utils/shuffle.js | 11 +++++++++++ test/utils/shuffle.spec.js | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/utils/shuffle.js create mode 100644 test/utils/shuffle.spec.js diff --git a/src/utils/shuffle.js b/src/utils/shuffle.js new file mode 100644 index 0000000..8333651 --- /dev/null +++ b/src/utils/shuffle.js @@ -0,0 +1,11 @@ +export default collection => { + let i, j, k; + const result = [...collection]; + for (i = collection.length; i > 0; i--) { + j = Math.floor(Math.random() * i); + k = result[i - 1]; + result[i - 1] = result[j]; + result[j] = k; + } + return result; +} diff --git a/test/utils/shuffle.spec.js b/test/utils/shuffle.spec.js new file mode 100644 index 0000000..2bf5e10 --- /dev/null +++ b/test/utils/shuffle.spec.js @@ -0,0 +1,17 @@ +'use strict'; +const expect = require('chai').expect; +const shuffle = require('../../src/utils/shuffle').default; + +describe('shuffle', () => { + it('should shuffle an array', () => { + const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + const result = shuffle(collection); + expect(collection).not.to.eql(result); + }); + + it('should not modify the passed in collection', () => { + const collection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + shuffle(collection); + expect(collection).to.eql([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + }); +}); From ba36c3ecba57da5ab85b043d92b036c7b49f9c06 Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 9 Jul 2017 22:49:54 +0100 Subject: [PATCH 16/21] Implemented a basic username faker. --- src/faker/internet.js | 14 ++++++++++++-- test/faker/internet.spec.js | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 6617282..70fb0f3 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -1,4 +1,5 @@ import { itemFromCollection, randomNumber } from '../utils/random'; +import shuffle from '../utils/shuffle'; const data = require('../../data/internet.json'); const nameData = require('../../data/name.json'); @@ -29,8 +30,17 @@ export function safeEmail(name=null) { ].join('@'); } -export function userName() { - return itemFromCollection(data['userNames']); +export function userName(specifier=null, separators=null) { + const userNameSeparator = itemFromCollection(separators || ['.', '_']); + if (typeof specifier === 'string') { + return shuffle(specifier.match(/\w+/g).map(x => x)).join(userNameSeparator); + } + const firstName = itemFromCollection(nameData['firstNames']).toLowerCase(); + const lastName = itemFromCollection(nameData['lastNames']).toLowerCase(); + return itemFromCollection([ + firstName, + [firstName, lastName].join(userNameSeparator) + ]); } export function password(minLength=8, maxLength=16, mixCase=true, specialChars=false) { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index b0f47c9..d7b2f90 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -15,6 +15,20 @@ describe('Internet', () => { }); describe('#userName', () => { + it('should return a username', () => { + expect(Internet.userName()).to.match(/^\w+(?:(\.|\_)\w+)?$/); + }); + + it('should return a username based off the specifier', () => { + const userName = Internet.userName('test user'); + expect(userName).to.match(/test/); + expect(userName).to.match(/user/); + expect(userName).to.match(/\w+(\.|\_)\w+/); + }); + + it('should return a username with the specified separator', () => { + expect(Internet.userName('test user', ['#'])).to.match(/\w+\#\w+/); + }); }); describe('#password', () => { From ff4c7cfbc6c2e58506c6268677b7237a0a686e52 Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 15 Oct 2017 21:21:00 +0100 Subject: [PATCH 17/21] Implemented the ipV4Address, privateIpV4Address and privateIpV4Address methods. --- src/faker/internet.js | 39 ++++++++++++++++++++++++++ test/faker/internet.spec.js | 56 +++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 70fb0f3..ca69af7 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -8,6 +8,25 @@ const loremData = require('../../data/lorem.json'); // 0-9, a-z const CHARACTERS = [...Array(10).keys()].concat([...Array(26).keys()].map(i => String.fromCharCode(97+i))); const SYMBOLS = ['!', '@', '#', '$', '%', '^', '&', '*']; +const PRIVATE_NET_REGEX = [ + /^10\./, // 10.0.0.0 – 10.255.255.255 + /^100\.(6[4-9]|[7-9]\d|1[0-1]\d|12[0-7])\./, // 100.64.0.0 – 100.127.255.255 + /^127\./, // 127.0.0.0 – 127.255.255.255 + /^169\.254\./, // 169.254.0.0 – 169.254.255.255 + /^172\.(1[6-9]|2\d|3[0-1])\./, // 172.16.0.0 – 172.31.255.255 + /^192\.0\.0\./, // 192.0.0.0 – 192.0.0.255 + /^192\.168\./, // 192.168.0.0 – 192.168.255.255 + /^198\.(1[8-9])\./ // 198.18.0.0 – 198.19.255.255 +]; +const RESERVED_NETS_REGEX = [ + /^0\./, // 0.0.0.0 – 0.255.255.255 + /^192\.0\.2\./, // 192.0.2.0 – 192.0.2.255 + /^192\.88\.99\./, // 192.88.99.0 – 192.88.99.255 + /^198\.51\.100\./, // 198.51.100.0 – 198.51.100.255 + /^203\.0\.113\./, // 203.0.113.0 – 203.0.113.255 + /^(22[4-9]|23\d)\./, // 224.0.0.0 – 239.255.255.255 + /^(24\d|25[0-5])\./ // 240.0.0.0 – 255.255.255.254 and 255.255.255.255 +]; export function email(name=null) { return [ @@ -77,12 +96,24 @@ export function domainSuffix() { } export function ipV4Address() { + return [ + randomNumber(2, 254), + randomNumber(2, 254), + randomNumber(2, 254), + randomNumber(2, 254) + ].join('.'); } export function privateIPV4Address() { + let addr; + do { addr = ipV4Address(); } while (!privateNetChecker(addr)); + return addr; } export function publicIPV4Address() { + let addr; + do { addr = ipV4Address(); } while (reservedNetChecker(addr)); + return addr; } export function ipV4Cidr() { @@ -108,3 +139,11 @@ export function slug(words='', glue='') { .replace(/\s+/g, glue || itemFromCollection(['-', '_', '.'])) .toLowerCase(); } + +function privateNetChecker(addr) { + return PRIVATE_NET_REGEX.some(x => addr.match(x)); +} + +function reservedNetChecker(addr) { + return [...PRIVATE_NET_REGEX, ...RESERVED_NETS_REGEX].some(x => addr.match(x)); +} diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index d7b2f90..90e5598 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -97,13 +97,63 @@ describe('Internet', () => { }); }); - describe('#ipV4_address', () => { + describe('#ipV4Address', () => { + it('should return an IPv4 address', () => { + [...Array(100).keys()].forEach(_ => { + const addr = Internet.ipV4Address(); + const octets = addr.split('.').map(x => parseInt(x)); + expect(addr).to.match(/^\d+\.\d+\.\d+\.\d+$/); + expect(Math.max(...octets)).to.be.below(255); + }); + }); }); - describe('#privateIpV4_address', () => { + describe('#privateIPV4Address', () => { + it('should return a private IPv4 address', () => { + const regexps = [ + /^10\./, // 10.0.0.0 – 10.255.255.255 + /^100\.(6[4-9]|[7-9]\d|1[0-1]\d|12[0-7])\./, // 100.64.0.0 – 100.127.255.255 + /^127\./, // 127.0.0.0 – 127.255.255.255 + /^169\.254\./, // 169.254.0.0 – 169.254.255.255 + /^172\.(1[6-9]|2\d|3[0-1])\./, // 172.16.0.0 – 172.31.255.255 + /^192\.0\.0\./, // 192.0.0.0 – 192.0.0.255 + /^192\.168\./, // 192.168.0.0 – 192.168.255.255 + /^198\.(1[8-9])\./ // 198.18.0.0 – 198.19.255.255 + ]; + const expected = new RegExp(regexps.map(x => `(${x.source})`).join('|')); + [...Array(100).keys()].forEach(_ => { + expect(Internet.privateIPV4Address()).to.match(expected); + }); + }); }); - describe('#publicIpV4_address', () => { + describe('#publicIPV4Address', () => { + it('should return a public IPv4 address', () => { + const privateRegexps = [ + /^10\./, // 10.0.0.0 – 10.255.255.255 + /^100\.(6[4-9]|[7-9]\d|1[0-1]\d|12[0-7])\./, // 100.64.0.0 – 100.127.255.255 + /^127\./, // 127.0.0.0 – 127.255.255.255 + /^169\.254\./, // 169.254.0.0 – 169.254.255.255 + /^172\.(1[6-9]|2\d|3[0-1])\./, // 172.16.0.0 – 172.31.255.255 + /^192\.0\.0\./, // 192.0.0.0 – 192.0.0.255 + /^192\.168\./, // 192.168.0.0 – 192.168.255.255 + /^198\.(1[8-9])\./ // 198.18.0.0 – 198.19.255.255 + ]; + const reservedRegexps = [ + /^0\./, // 0.0.0.0 – 0.255.255.255 + /^192\.0\.2\./, // 192.0.2.0 – 192.0.2.255 + /^192\.88\.99\./, // 192.88.99.0 – 192.88.99.255 + /^198\.51\.100\./, // 198.51.100.0 – 198.51.100.255 + /^203\.0\.113\./, // 203.0.113.0 – 203.0.113.255 + /^(22[4-9]|23\d)\./, // 224.0.0.0 – 239.255.255.255 + /^(24\d|25[0-5])\./ // 240.0.0.0 – 255.255.255.254 and 255.255.255.255 + ]; + [...Array(100).keys()].forEach(_ => { + const addr = Internet.publicIPV4Address(); + privateRegexps.forEach(regexp => expect(addr).not.to.match(regexp)); + reservedRegexps.forEach(regexp => expect(addr).not.to.match(regexp)); + }); + }); }); describe('#ipV4_cidr', () => { From 48b1bd61c8285d5eab2010b441a6023cfab102c4 Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 15 Oct 2017 21:29:10 +0100 Subject: [PATCH 18/21] Implemented the ipV4CIDR method. --- src/faker/internet.js | 3 ++- test/faker/internet.spec.js | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index ca69af7..6a056d4 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -116,7 +116,8 @@ export function publicIPV4Address() { return addr; } -export function ipV4Cidr() { +export function ipV4CIDR() { + return `${ipV4Address()}/${randomNumber(1, 31)}`; } export function ipV6Address() { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 90e5598..63014b5 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -156,7 +156,14 @@ describe('Internet', () => { }); }); - describe('#ipV4_cidr', () => { + describe('#ipV4CIDR', () => { + it('should return a IPv4 Classless Inter-Domain Routing address', () => { + [...Array(100).keys()].forEach(_ => { + const addr = Internet.ipV4CIDR(); + expect(addr).to.match(/\/\d{1,2}$/); + expect(parseInt(addr.split('/')[1])).to.be.within(1, 32); + }); + }); }); describe('#ipV6_address', () => { From cda35dcd72472b794862329accc46362f647c09e Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 15 Oct 2017 21:29:47 +0100 Subject: [PATCH 19/21] Updated CIDR methods in docs. --- doc/internet.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/internet.md b/doc/internet.md index b47450c..2b1e3cb 100644 --- a/doc/internet.md +++ b/doc/internet.md @@ -53,11 +53,11 @@ Faker.Internet.privateIPV4Address() //=> "10.0.0.1" // Guaranteed not to be in the ip range from the private_ip_v4_address method. Faker.Internet.publicIPV4Address() //=> "24.29.18.175" -Faker.Internet.ipV4Cidr() //=> "24.29.18.175/21" +Faker.Internet.ipV4CIDR() //=> "24.29.18.175/21" Faker.Internet.ipV6Address() //=> "ac5f:d696:3807:1d72:2eb5:4e81:7d2b:e1df" -Faker.Internet.ipV6Cidr() //=> "ac5f:d696:3807:1d72:2eb5:4e81:7d2b:e1df/78" +Faker.Internet.ipV6CIDR() //=> "ac5f:d696:3807:1d72:2eb5:4e81:7d2b:e1df/78" // Optional argument prefix='' Faker.Internet.macAddress() //=> "e6:0d:00:11:ed:4f" From 3fe5794be623b2764c1653f7ab96b09206ffbe35 Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 15 Oct 2017 21:45:53 +0100 Subject: [PATCH 20/21] Implemented the IPv6 methods. --- src/faker/internet.js | 6 ++++-- test/faker/internet.spec.js | 12 ++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index 6a056d4..a4a4d21 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -117,13 +117,15 @@ export function publicIPV4Address() { } export function ipV4CIDR() { - return `${ipV4Address()}/${randomNumber(1, 31)}`; + return `${ipV4Address()}/${randomNumber(1, 32)}`; } export function ipV6Address() { + return [...Array(8).keys()].map(_ => randomNumber(4096, 65536).toString(16)).join(':'); } -export function ipV6Cidr() { +export function ipV6CIDR() { + return `${ipV6Address()}/${randomNumber(1, 128)}`; } export function macAddress(prefix='') { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 63014b5..77379e1 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -166,10 +166,18 @@ describe('Internet', () => { }); }); - describe('#ipV6_address', () => { + describe('#ipV6Address', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.ipV6Address()).to.match(/^[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}:[0-9a-f]{4}$/); + }); }); - describe('#ipV6_cidr', () => { + describe('#ipV6CIDR', () => { + [...Array(100).keys()].forEach(_ => { + const addr = Internet.ipV6CIDR(); + expect(addr).to.match(/\/\d{1,3}$/); + expect(parseInt(addr.split('/')[1])).to.be.within(1, 128); + }); }); describe('#macAddress', () => { From ad894ba7ab6be91b494c4ff08ffd610cc8b7c2cd Mon Sep 17 00:00:00 2001 From: mrstebo Date: Sun, 15 Oct 2017 21:52:00 +0100 Subject: [PATCH 21/21] Implemented the URL method. --- src/faker/internet.js | 5 ++++- test/faker/internet.spec.js | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/faker/internet.js b/src/faker/internet.js index a4a4d21..0d34043 100644 --- a/src/faker/internet.js +++ b/src/faker/internet.js @@ -134,7 +134,10 @@ export function macAddress(prefix='') { return [...prefixDigits, ...addressDigits].map(x => x.toString(16)).join(':'); } -export function url() { +export function url(host=null, path=null, scheme='http') { + host = host || domainName(); + path = path || `/${userName()}`; + return `${scheme}://${host}${path}`; } export function slug(words='', glue='') { diff --git a/test/faker/internet.spec.js b/test/faker/internet.spec.js index 77379e1..9c4c3d5 100644 --- a/test/faker/internet.spec.js +++ b/test/faker/internet.spec.js @@ -195,6 +195,29 @@ describe('Internet', () => { }); describe('#url', () => { + it('should return a URL', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.url()).to.match(/^http:\/\/.+\/.+$/); + }); + }); + + it('should return a URL with the specified host', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.url('myhost')).to.match(/^http:\/\/myhost\/.+$/); + }); + }); + + it('should return a URL with the specified path', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.url('myhost', '/mypath')).to.match(/^http:\/\/.+\/mypath$/); + }); + }); + + it('should return a URL with the specified scheme', () => { + [...Array(100).keys()].forEach(_ => { + expect(Internet.url('myhost', '/mypath', 'git')).to.match(/^git:\/\/.+\/.+$/); + }); + }); }); describe('#slug', () => {