Skip to content

Commit

Permalink
Merge pull request toptal#180 from seejohnrun/es6_generators
Browse files Browse the repository at this point in the history
ES6 generators
  • Loading branch information
seejohnrun authored Nov 1, 2017
2 parents e12805a + 3b6934e commit ee03e7c
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 63 deletions.
50 changes: 29 additions & 21 deletions lib/key_generators/dictionary.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
var fs = require('fs');

var DictionaryGenerator = function(options) {
//Options
if (!options) throw Error('No options passed to generator');
if (!options.path) throw Error('No dictionary path specified in options');

//Load dictionary
fs.readFile(options.path, 'utf8', (err, data) => {
if (err) throw err;
this.dictionary = data.split(/[\n\r]+/);
});
};
const fs = require('fs');

//Generates a dictionary-based key, of keyLength words
DictionaryGenerator.prototype.createKey = function(keyLength) {
var text = '';
for(var i = 0; i < keyLength; i++)
text += this.dictionary[Math.floor(Math.random() * this.dictionary.length)];
module.exports = class DictionaryGenerator {

return text;
};
constructor(options, readyCallback) {
// Check options format
if (!options) throw Error('No options passed to generator');
if (!options.path) throw Error('No dictionary path specified in options');

// Load dictionary
fs.readFile(options.path, 'utf8', (err, data) => {
if (err) throw err;

this.dictionary = data.split(/[\n\r]+/);

if (readyCallback) readyCallback();
});
}

module.exports = DictionaryGenerator;
// Generates a dictionary-based key, of keyLength words
createKey(keyLength) {
let text = '';

for (let i = 0; i < keyLength; i++) {
const index = Math.floor(Math.random() * this.dictionary.length);
text += this.dictionary[index];
}

return text;
}

};
46 changes: 20 additions & 26 deletions lib/key_generators/phonetic.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
// Draws inspiration from pwgen and http://tools.arantius.com/password
var PhoneticKeyGenerator = function() {
// No options
};

// Generate a phonetic key
PhoneticKeyGenerator.prototype.createKey = function(keyLength) {
var text = '';
var start = Math.round(Math.random());
for (var i = 0; i < keyLength; i++) {
text += (i % 2 == start) ? this.randConsonant() : this.randVowel();
}
return text;
const randOf = (collection) => {
return () => {
return collection[Math.floor(Math.random() * collection.length)];
};
};

PhoneticKeyGenerator.consonants = 'bcdfghjklmnpqrstvwxyz';
PhoneticKeyGenerator.vowels = 'aeiou';
// Helper methods to get an random vowel or consonant
const randVowel = randOf('aeiou');
const randConsonant = randOf('bcdfghjklmnpqrstvwxyz');

// Get an random vowel
PhoneticKeyGenerator.prototype.randVowel = function() {
return PhoneticKeyGenerator.vowels[
Math.floor(Math.random() * PhoneticKeyGenerator.vowels.length)
];
};
module.exports = class PhoneticKeyGenerator {

// Get an random consonant
PhoneticKeyGenerator.prototype.randConsonant = function() {
return PhoneticKeyGenerator.consonants[
Math.floor(Math.random() * PhoneticKeyGenerator.consonants.length)
];
};
// Generate a phonetic key of alternating consonant & vowel
createKey(keyLength) {
let text = '';
const start = Math.round(Math.random());

module.exports = PhoneticKeyGenerator;
for (let i = 0; i < keyLength; i++) {
text += (i % 2 == start) ? randConsonant() : randVowel();
}

return text;
}

};
31 changes: 16 additions & 15 deletions lib/key_generators/random.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
var RandomKeyGenerator = function(options) {
if (!options) {
options = {};
module.exports = class RandomKeyGenerator {

// Initialize a new generator with the given keySpace
constructor(options = {}) {
this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
}
this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
};

// Generate a random key
RandomKeyGenerator.prototype.createKey = function(keyLength) {
var text = '';
var index;
for (var i = 0; i < keyLength; i++) {
index = Math.floor(Math.random() * this.keyspace.length);
text += this.keyspace.charAt(index);
// Generate a key of the given length
createKey(keyLength) {
var text = '';

for (var i = 0; i < keyLength; i++) {
const index = Math.floor(Math.random() * this.keyspace.length);
text += this.keyspace.charAt(index);
}

return text;
}
return text;
};

module.exports = RandomKeyGenerator;
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@
},
"scripts": {
"start": "node server.js",
"test": "mocha"
"test": "mocha --recursive"
}
}
33 changes: 33 additions & 0 deletions test/key_generators/dictionary_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* global describe, it */

const assert = require('assert');

const fs = require('fs');

const Generator = require('../../lib/key_generators/dictionary');

describe('RandomKeyGenerator', function() {
describe('randomKey', function() {
it('should throw an error if given no options', () => {
assert.throws(() => {
new Generator();
}, Error);
});

it('should throw an error if given no path', () => {
assert.throws(() => {
new Generator({});
}, Error);
});

it('should return a key of the proper number of words from the given dictionary', () => {
const path = '/tmp/haste-server-test-dictionary';
const words = ['cat'];
fs.writeFileSync(path, words.join('\n'));

const gen = new Generator({path}, () => {
assert.equal('catcatcat', gen.createKey(3));
});
});
});
});
27 changes: 27 additions & 0 deletions test/key_generators/phonetic_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* global describe, it */

const assert = require('assert');

const Generator = require('../../lib/key_generators/phonetic');

const vowels = 'aeiou';
const consonants = 'bcdfghjklmnpqrstvwxyz';

describe('RandomKeyGenerator', () => {
describe('randomKey', () => {
it('should return a key of the proper length', () => {
const gen = new Generator();
assert.equal(6, gen.createKey(6).length);
});

it('should alternate consonants and vowels', () => {
const gen = new Generator();

const key = gen.createKey(3);

assert.ok(consonants.includes(key[0]));
assert.ok(consonants.includes(key[2]));
assert.ok(vowels.includes(key[1]));
});
});
});
19 changes: 19 additions & 0 deletions test/key_generators/random_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* global describe, it */

const assert = require('assert');

const Generator = require('../../lib/key_generators/random');

describe('RandomKeyGenerator', () => {
describe('randomKey', () => {
it('should return a key of the proper length', () => {
const gen = new Generator();
assert.equal(6, gen.createKey(6).length);
});

it('should use a key from the given keyset if given', () => {
const gen = new Generator({keyspace: 'A'});
assert.equal('AAAAAA', gen.createKey(6));
});
});
});

0 comments on commit ee03e7c

Please sign in to comment.