diff --git a/lib/key_generators/dictionary.js b/lib/key_generators/dictionary.js index 900ac29..0bcbc2e 100644 --- a/lib/key_generators/dictionary.js +++ b/lib/key_generators/dictionary.js @@ -1,24 +1,32 @@ -var fs = require('fs'); +const 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'); +module.exports = class DictionaryGenerator { + + 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(); + }); + } + + // 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; + } - //Load dictionary - fs.readFile(options.path, 'utf8', (err, data) => { - if (err) throw err; - this.dictionary = data.split(/[\n\r]+/); - }); }; - -//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)]; - - return text; -}; - -module.exports = DictionaryGenerator; diff --git a/lib/key_generators/phonetic.js b/lib/key_generators/phonetic.js index cb13a19..f281f6b 100644 --- a/lib/key_generators/phonetic.js +++ b/lib/key_generators/phonetic.js @@ -1,33 +1,27 @@ // Draws inspiration from pwgen and http://tools.arantius.com/password -var PhoneticKeyGenerator = function() { - // No options + +const randOf = (collection) => { + return () => { + return collection[Math.floor(Math.random() * collection.length)]; + }; }; -// 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(); +// Helper methods to get an random vowel or consonant +const randVowel = randOf('aeiou'); +const randConsonant = randOf('bcdfghjklmnpqrstvwxyz'); + +module.exports = class PhoneticKeyGenerator { + + // Generate a phonetic key of alternating consonant & vowel + createKey(keyLength) { + let text = ''; + const start = Math.round(Math.random()); + + for (let i = 0; i < keyLength; i++) { + text += (i % 2 == start) ? randConsonant() : randVowel(); + } + + return text; } - return text; + }; - -PhoneticKeyGenerator.consonants = 'bcdfghjklmnpqrstvwxyz'; -PhoneticKeyGenerator.vowels = 'aeiou'; - -// Get an random vowel -PhoneticKeyGenerator.prototype.randVowel = function() { - return PhoneticKeyGenerator.vowels[ - Math.floor(Math.random() * PhoneticKeyGenerator.vowels.length) - ]; -}; - -// Get an random consonant -PhoneticKeyGenerator.prototype.randConsonant = function() { - return PhoneticKeyGenerator.consonants[ - Math.floor(Math.random() * PhoneticKeyGenerator.consonants.length) - ]; -}; - -module.exports = PhoneticKeyGenerator; diff --git a/lib/key_generators/random.js b/lib/key_generators/random.js index cd35f3d..767e26b 100644 --- a/lib/key_generators/random.js +++ b/lib/key_generators/random.js @@ -1,19 +1,20 @@ -var RandomKeyGenerator = function(options) { - if (!options) { - options = {}; - } - this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -}; +module.exports = class RandomKeyGenerator { -// 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); + // Initialize a new generator with the given keySpace + constructor(options = {}) { + this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; } - return text; -}; -module.exports = RandomKeyGenerator; + // 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; + } + +}; diff --git a/package.json b/package.json index df12c47..1e87fa3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,6 @@ }, "scripts": { "start": "node server.js", - "test": "mocha" + "test": "mocha --recursive" } } diff --git a/test/key_generators/dictionary_spec.js b/test/key_generators/dictionary_spec.js new file mode 100644 index 0000000..72718c7 --- /dev/null +++ b/test/key_generators/dictionary_spec.js @@ -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)); + }); + }); + }); +}); diff --git a/test/key_generators/phonetic_spec.js b/test/key_generators/phonetic_spec.js new file mode 100644 index 0000000..14ad9e8 --- /dev/null +++ b/test/key_generators/phonetic_spec.js @@ -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])); + }); + }); +}); diff --git a/test/key_generators/random_spec.js b/test/key_generators/random_spec.js new file mode 100644 index 0000000..537a809 --- /dev/null +++ b/test/key_generators/random_spec.js @@ -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)); + }); + }); +});