markov-strings
Advanced tools
Comparing version 0.1.0 to 1.0.0
48
index.js
'use strict'; | ||
var _ = require('lodash'); | ||
const _ = require('lodash'); | ||
@@ -25,14 +25,23 @@ class Generator { | ||
_.assignIn(this.options, options); | ||
this.buildCorpus(); | ||
} | ||
buildCorpus() { | ||
let options = this.options; | ||
return new Promise((resolve, reject) => { | ||
try { | ||
resolve(this.buildCorpusSync()); | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
buildCorpusSync() { | ||
const options = this.options; | ||
this.data.forEach(line => { | ||
let words = line.split(' '); | ||
const words = line.split(' '); | ||
// Start words | ||
let start = _.slice(words, 0, options.stateSize).join(' '); | ||
const start = _.slice(words, 0, options.stateSize).join(' '); | ||
if (!_.includes(this.startWords, start)) { | ||
@@ -43,3 +52,3 @@ this.startWords.push(start); | ||
// End words | ||
var end = _.slice(words, words.length - options.stateSize, words.length).join(' '); | ||
const end = _.slice(words, words.length - options.stateSize, words.length).join(' '); | ||
if (!_.includes(this.endWords, end)) { | ||
@@ -50,5 +59,5 @@ this.endWords.push(end); | ||
// Build corpus | ||
for (var i = 0; i < words.length - 1; i++) { | ||
var curr = _.slice(words, i, i + options.stateSize).join(' '); | ||
var next = _.slice(words, i + options.stateSize, i + options.stateSize * 2).join(' '); | ||
for (let i = 0; i < words.length - 1; i++) { | ||
const curr = _.slice(words, i, i + options.stateSize).join(' '); | ||
const next = _.slice(words, i + options.stateSize, i + options.stateSize * 2).join(' '); | ||
if (!next || next.split(' ').length != options.stateSize) { | ||
@@ -72,2 +81,13 @@ continue; | ||
generateSentence(options, check) { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
resolve(this.generateSentenceSync(options, check)) | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
generateSentenceSync(options, check) { | ||
options = options ? options : {}; | ||
@@ -77,3 +97,3 @@ _.assignIn(this.options, options); | ||
let corpus = _.cloneDeep(this.corpus); | ||
const corpus = _.cloneDeep(this.corpus); | ||
const max = options.maxTries; | ||
@@ -84,3 +104,3 @@ | ||
let ended = false; | ||
let arr = [_.sample(this.startWords)]; | ||
const arr = [_.sample(this.startWords)]; | ||
let score = 0; | ||
@@ -90,4 +110,4 @@ | ||
while (true) { | ||
let key = arr[arr.length - 1]; // Last value in array | ||
let state = _.sample(corpus[key]); | ||
const key = arr[arr.length - 1]; // Last value in array | ||
const state = _.sample(corpus[key]); | ||
@@ -94,0 +114,0 @@ // Sentence cannot be finished |
{ | ||
"name": "markov-strings", | ||
"version": "0.1.0", | ||
"version": "1.0.0", | ||
"description": "A Markov string generator", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -20,9 +20,9 @@ [![Build Status](https://travis-ci.org/scambier/markov-strings.svg?branch=master)](https://travis-ci.org/scambier/markov-strings) | ||
```javascript | ||
let Markov = require('markov-strings'); | ||
const Markov = require('markov-strings'); | ||
// An array of strings | ||
let data = [/* insert a few hundreds sentences here */]; | ||
const data = [/* insert a few hundreds/thousands sentences here */]; | ||
// Some options to generate Twitter-ready strings | ||
let options = { | ||
const options = { | ||
maxLength: 140, | ||
@@ -34,25 +34,35 @@ minWords: 10, | ||
// Instantiate the generator | ||
let markov = new Markov(data, options); | ||
const markov = new Markov(data, options); | ||
// Generate some tweets | ||
let tweets = []; | ||
for (let i = 0; i < 10; i++) { | ||
tweets.push(markov.generateSentence()); | ||
} | ||
// Build the corpus | ||
markov.buildCorpus() | ||
.then(() => { | ||
// Generate some tweets | ||
const tweets = []; | ||
for (let i = 0; i < 10; i++) { | ||
markov.generateSentence() | ||
.then(result => { | ||
tweets.push(result); | ||
}); | ||
} | ||
// Generate a shorter tweet to add a link | ||
let shorterTweet = markov.generateSentence({ | ||
maxLength: 140-24 | ||
}); | ||
shorterTweet += ' https://github.com/scambier/markov-strings'; // Links always take 23 characters in a tweet | ||
// Generate a shorter tweet to add a link | ||
markov.generateSentence({ | ||
maxLength: 140 - 24 | ||
}) | ||
.then(shorterTweet => { | ||
shorterTweet += ' https://github.com/scambier/markov-strings'; // Links always take 23 characters in a tweet | ||
console.log(shorterTweet); | ||
/* | ||
Possible output: | ||
{ | ||
string: 'lorem ipsum dolor sit amet (etc.) https://github.com/scambier/markov-strings', | ||
score: 42 | ||
} | ||
*/ | ||
console.log(shorterTweet); | ||
/* | ||
Possible output: | ||
{ | ||
string: 'lorem ipsum dolor sit amet (etc.) https://github.com/scambier/markov-strings', | ||
score: 42 | ||
} | ||
*/ | ||
}) | ||
}); | ||
``` | ||
@@ -112,4 +122,17 @@ ## API | ||
##### maxTries | ||
Type: `integer` | ||
Default: `10000` | ||
Sentence generation can (will) take multiple tries to create one that will fulfill all restrictions. | ||
If this value is exceeded, an error will be thrown. | ||
#### markov.buildCorpus() | ||
Return a Promise that will resolve to nothing. | ||
This function **must** be called to build the corpus for Markov generation. | ||
It will iterate over all words for all strings from your `data` parameter, so it can take some time depending on its size. | ||
#### markov.generateSentence([options]) | ||
Generate a random sentence. | ||
Return a Promise that will resolve to an object `{string, score}` | ||
@@ -121,6 +144,3 @@ ##### options | ||
## Todo | ||
The generator should return a Promise, to not hang the thread. | ||
## Running the tests | ||
`npm test` |
102
test/test.js
'use strict'; | ||
var expect = require('chai').expect; | ||
const expect = require('chai').expect; | ||
var Generator = require('../index'); | ||
var data = [ | ||
const data = [ | ||
"Lorem ipsum dolor sit amet", | ||
@@ -18,5 +16,11 @@ "Lorem ipsum duplicate start words", | ||
const Generator = require('../index'); | ||
const generator = new Generator(data); | ||
beforeEach(function(done) { | ||
generator.buildCorpus().then(done); | ||
}); | ||
describe('Options parser', function() { | ||
it('should have the right values', function() { | ||
var generator = new Generator([], {}); | ||
expect(generator.options.stateSize).to.equal(2); | ||
@@ -28,10 +32,5 @@ }); | ||
var generator; | ||
before(function() { | ||
generator = new Generator(data) | ||
}); | ||
describe('StartWords array', function() { | ||
it('should contain the right values', function() { | ||
var start = generator.startWords; | ||
const start = generator.startWords; | ||
expect(start).to.contain('Lorem ipsum'); | ||
@@ -55,3 +54,3 @@ expect(start).to.contain('Consectetur adipiscing'); | ||
it('should contain the right values', function() { | ||
var end = generator.endWords; | ||
const end = generator.endWords; | ||
expect(end).to.contain('sit amet'); | ||
@@ -68,3 +67,3 @@ expect(end).to.contain('start words'); | ||
it('should have the right values for the right keys', function() { | ||
var corpus = generator.corpus; | ||
const corpus = generator.corpus; | ||
expect(corpus['Lorem ipsum']).to.contain('dolor sit'); | ||
@@ -79,12 +78,7 @@ expect(corpus['Lorem ipsum']).to.contain('duplicate start'); | ||
var generator; | ||
before(function() { | ||
generator = new Generator(data) | ||
}); | ||
it('should output a sentence', function() { | ||
let result = generator.generateSentence({ | ||
stateSize: 1 | ||
}); | ||
expect(result).to.exist; | ||
generator.generateSentence({stateSize: 1}) | ||
.then(result => { | ||
expect(result).to.exist; | ||
}); | ||
}); | ||
@@ -94,7 +88,6 @@ | ||
for (let i = 0; i < 10; i++) { | ||
expect(() => { | ||
generator.generateSentence({ | ||
stateSize: 3 | ||
}).to.throw(Error); | ||
}) | ||
generator.generateSentence({stateSize: 3}) | ||
.then(result => { | ||
expect(result).to.throw(Error); | ||
}); | ||
} | ||
@@ -104,8 +97,9 @@ }); | ||
it('should end with a value from endWords', function() { | ||
let result = generator.generateSentence().string; | ||
let arr = result.split(' '); | ||
let end = arr.slice(arr.length - 2, arr.length); | ||
for (let i = 0; i < 10; i++) { | ||
expect(generator.endWords).to.contain(end.join(' ')); | ||
generator.generateSentence() | ||
.then(result => { | ||
const arr = result.split(' '); | ||
const end = arr.slice(arr.length - 2, arr.length); | ||
expect(generator.endWords).to.contain(end.join(' ')); | ||
}); | ||
} | ||
@@ -115,38 +109,44 @@ }); | ||
it('should reject the sentence', function() { | ||
let options = {minWords: 5, maxTries: 10}; | ||
expect(() => { | ||
generator.generateSentence(options, result => result.split(' ').length < 5) | ||
}).to.throw(Error); | ||
const options = {minWords: 5, maxTries: 10}; | ||
generator.generateSentence(options, result => result.split(' ').length < 5) | ||
.then(result => { | ||
expect(result).to.throw(Error); | ||
}); | ||
}); | ||
it('should accept the sentence', function() { | ||
expect(() => { | ||
generator.generateSentence({}, result => true) | ||
}).to.exist; | ||
generator.generateSentence({}, result => true) | ||
.then(result => { | ||
expect(result).to.exist; | ||
}); | ||
}); | ||
it('should reject because maxLength is unattainable', function() { | ||
expect(() => { | ||
generator.generateSentence({maxTries: 10, maxLength: 1, minWords: 0, maxWords: 0}) | ||
}).to.throw(Error); | ||
generator.generateSentence({maxTries: 10, maxLength: 1, minWords: 0, maxWords: 0}) | ||
.then(result => { | ||
expect(result).to.throw(Error); | ||
}); | ||
}); | ||
it('should reject because minWords is unattainable', function() { | ||
expect(() => { | ||
generator.generateSentence({maxTries: 10, minWords: 100}) | ||
}).to.throw(Error); | ||
generator.generateSentence({maxTries: 10, minWords: 100}) | ||
.then(result => { | ||
expect(result).to.throw(Error); | ||
}); | ||
}); | ||
it('should reject because minScore is unattainable', function() { | ||
expect(() => { | ||
generator.generateSentence({maxTries: 10, minScore: 20}) | ||
}).to.throw(Error); | ||
generator.generateSentence({maxTries: 10, minScore: 20}) | ||
.then(result => { | ||
expect(result).to.throw(Error); | ||
}); | ||
}); | ||
it('should reject because maxWords is unattainable', function() { | ||
expect(() => { | ||
generator.generateSentence({maxTries: 10, maxWords: 1, minWords: 0}) | ||
}).to.throw(Error); | ||
generator.generateSentence({maxTries: 10, maxWords: 1, minWords: 0}) | ||
.then(result => { | ||
expect(result).to.throw(Error); | ||
}); | ||
}); | ||
}); |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
14411
242
1
143