marky_markov 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -33,11 +33,23 @@ of the dictionary name.
33
33
  puts markov.generate_n_words 10
34
34
  markov.save_dictionary! # Saves the modified dictionary/creates one if it didn't exist.
35
35
 
36
- If you keep look at generate_n_words and wonder why you can't put a
36
+ If you keep looking at generate_n_words and wonder why you can't put a
37
37
  number in there, well, you can!
38
38
 
39
39
  markov.generate_20_words
40
40
 
41
+ The default dictionary depth is two words.
42
+ `{"I hope" => {"this" => 1},
43
+ "hope this" => {"makes" => 1},
44
+ "this makes" => {"sense" => 1}}`
45
+ but it can be set to a depth between 1 and 9 upon dictionary creation
46
+
47
+ markov = MarkyMarkov::Dictionary.new('dictionary', 3)
48
+
49
+ creates a dictionary with a depth of three words.
50
+ `{"I hope this" => {"makes" => 1},
51
+ "hope this makes" => {"sense" => 1}`
52
+
41
53
  If you want to delete a dictionary you call it upon the Dictionary class itself while
42
54
  passing in the filename/location.
43
55
 
data/bin/marky_markov CHANGED
@@ -4,7 +4,6 @@
4
4
  require 'optparse'
5
5
  require 'marky_markov'
6
6
 
7
- #if __FILE__ == $0
8
7
  options = {}
9
8
  opt_parser = OptionParser.new do |opts|
10
9
  opts.banner = "Usage: marky-markov COMMAND [OPTIONS]"
@@ -17,7 +16,7 @@ opt_parser = OptionParser.new do |opts|
17
16
  opts.separator "Options"
18
17
 
19
18
  options[:dictionary] = "#{ENV["HOME"]}/.marky_markov_dictionary"
20
- opts.on('-d', '--dictionary FILE', 'Use custom dictionary location') do |file|
19
+ opts.on('-l', '--location DICTIONARY', 'Use custom dictionary location') do |file|
21
20
  options[:dictionary] = file
22
21
  end
23
22
 
@@ -32,6 +31,12 @@ opt_parser = OptionParser.new do |opts|
32
31
  options[:source] = file
33
32
  end
34
33
 
34
+ options[:depth] = 2
35
+ opts.on('-d', '--depth 1-9', 'Set dictionary depth. The higher the number
36
+ , the less random the sentence will be. Must be between 1 and 9.') do |number|
37
+ options[:depth] = number.to_i
38
+ end
39
+
35
40
  options[:resetdictionary] = false
36
41
  opts.on('--reset', "WARNING: Deletes default dictionary." ) do
37
42
  options[:resetdictionary] = true
@@ -53,7 +58,7 @@ end
53
58
  case ARGV[0]
54
59
  when "speak"
55
60
  if options[:source]
56
- markov = MarkyMarkov::TemporaryDictionary.new
61
+ markov = MarkyMarkov::TemporaryDictionary.new(options[:depth])
57
62
  markov.parse_file(options[:source])
58
63
  else
59
64
  unless File.exists?("#{options[:dictionary]}.mmd")
@@ -66,7 +71,7 @@ when "speak"
66
71
  STDOUT.puts markov.generate_n_words(options[:wordcount])
67
72
  when "read"
68
73
  source = ARGV[1] || options[:source]
69
- markov = MarkyMarkov::Dictionary.new(options[:dictionary])
74
+ markov = MarkyMarkov::Dictionary.new(options[:dictionary], options[:depth])
70
75
  markov.parse_file(source)
71
76
  markov.save_dictionary!
72
77
  STDOUT.puts "Added #{source} to dictionary."
@@ -76,7 +81,7 @@ when "listen"
76
81
  STDOUT.puts markov.generate_n_words(options[:wordcount])
77
82
  else
78
83
  unless STDIN.tty?
79
- markov = MarkyMarkov::TemporaryDictionary.new
84
+ markov = MarkyMarkov::TemporaryDictionary.new(options[:depth])
80
85
  markov.parse_string(STDIN.read)
81
86
  STDOUT.puts markov.generate_n_words(options[:wordcount])
82
87
  else
@@ -1,8 +1,9 @@
1
1
  # @private
2
- class OneWordDictionary
3
- attr_accessor :dictionary
4
- def initialize
2
+ class MarkovDictionary
3
+ attr_accessor :dictionary, :depth
4
+ def initialize(depth=2)
5
5
  @dictionary = {}
6
+ @depth = depth
6
7
  end
7
8
 
8
9
  # If File does not exist.
@@ -36,11 +37,10 @@ class OneWordDictionary
36
37
  # @example Add a string
37
38
  # parse_source("Hi, how are you doing?", false)
38
39
  def parse_source(source, file=true)
39
- # Special case for last word in source file as it has no words following it.
40
40
  contents = file ? open_source(source) : contents = source.split
41
- contents.each_cons(2) do |first, second|
42
- self.add_word(first, second)
41
+ contents.each_cons(@depth+1) do |words|
42
+ self.add_word(words[0..-2].join(' '), words[-1])
43
43
  end
44
- @dictionary[(contents.last)] ||= Hash.new(0)
44
+ @dictionary[contents.last(@depth).join(' ')] ||= Hash.new(0)
45
45
  end
46
46
  end
@@ -1,7 +1,8 @@
1
1
  # @private
2
- class OneWordSentenceGenerator
2
+ class MarkovSentenceGenerator
3
3
  def initialize(dictionary)
4
4
  @dictionary = dictionary
5
+ @depth = @dictionary.depth
5
6
  end
6
7
 
7
8
  # Returns a random word via picking a random key from the dictionary.
@@ -15,6 +16,20 @@ class OneWordSentenceGenerator
15
16
  keys[rand(keys.length)]
16
17
  end
17
18
 
19
+ # Generates a random capitalized word via picking a random key from the
20
+ # dictionary and recurring if the word is lowercase.
21
+ #
22
+ # (see #random_word)
23
+ def random_capitalized_word
24
+ keys = @dictionary.dictionary.keys
25
+ x = keys[rand(keys.length)]
26
+ if /[A-Z]/ =~ x[0]
27
+ return x
28
+ else
29
+ random_capitalized_word
30
+ end
31
+ end
32
+
18
33
  # Returns a word based upon the likelyhood of it appearing after the supplied word.
19
34
  #
20
35
  def weighted_random(lastword)
@@ -36,10 +51,11 @@ class OneWordSentenceGenerator
36
51
  #
37
52
  def generate(wordcount)
38
53
  sentence = []
39
- sentence << random_word
54
+ sentence.concat(random_capitalized_word.split)
40
55
  (wordcount-1).times do
41
- sentence << weighted_random(sentence.last)
56
+ sentence.concat(weighted_random(sentence.last(@depth).join(' ')).split)
42
57
  end
58
+ sentence.pop(sentence.length-wordcount)
43
59
  sentence.join(' ')
44
60
  end
45
61
  end
@@ -1,27 +1,36 @@
1
1
  require 'yajl'
2
- require_relative 'two_word_dictionary'
2
+ require_relative 'markov_dictionary'
3
3
 
4
4
  # @private
5
- class PersistentDictionary < TwoWordDictionary
5
+ class PersistentDictionary < MarkovDictionary
6
+
7
+ class DepthNotInRangeError < Exception
8
+ end
9
+
6
10
  # Creates a PersistentDictionary object using the supplied dictionary file.
7
11
  #
8
- # @note Do not include the .mmd file extension in the name of the dictionary.
9
- # It will be automatically appended.
10
12
  # @param [File] dictionary Name of dictionary file to create/open.
13
+ # @param [Int] depth The dictionary depth. 2 word dictionary default.
11
14
  # @return [Object] PersistentDictionary object.
12
- attr_reader :dictionarylocation
13
- def initialize(dictionary)
15
+ attr_reader :dictionarylocation, :depth
16
+ def initialize(dictionary, depth=2)
17
+ @depth = depth
18
+ unless (1..9).include?(depth)
19
+ raise DepthNotInRangeError.new("Depth must be between 1 and 9")
20
+ end
14
21
  @dictionarylocation = dictionary
15
22
  self.open_dictionary
16
23
  end
17
24
 
25
+
18
26
  # Opens the dictionary objects dictionary file.
19
27
  # If the file exists it assigns the contents to a hash,
20
28
  # otherwise it creates an empty hash.
21
29
  def open_dictionary
22
30
  if File.exists?(@dictionarylocation)
23
- File.open(@dictionarylocation,'r') do |f|
24
- @dictionary = Yajl::Parser.parse(f)
31
+ File.open(@dictionarylocation,'r').each do |f|
32
+ @depth = f[0].to_i
33
+ @dictionary = Yajl::Parser.parse(f[1..-1])
25
34
  end
26
35
  else
27
36
  @dictionary = {}
@@ -33,7 +42,7 @@ class PersistentDictionary < TwoWordDictionary
33
42
  def save_dictionary!
34
43
  json = Yajl::Encoder.encode(@dictionary)
35
44
  File.open(@dictionarylocation, 'w') do |f|
36
- f.puts json
45
+ f.puts @depth.to_s + json
37
46
  end
38
47
  true
39
48
  end
data/lib/marky_markov.rb CHANGED
@@ -2,24 +2,28 @@
2
2
  #A Markov Chain generator.
3
3
 
4
4
  require_relative 'marky_markov/persistent_dictionary'
5
- require_relative 'marky_markov/two_word_sentence_generator'
5
+ require_relative 'marky_markov/markov_sentence_generator'
6
6
 
7
- # @version = 0.1.2
7
+ # @version = 0.1.3
8
8
  # @author Matt Furden
9
9
  # Module containing TemporaryDictionary and Dictionary for creation of
10
10
  # Markov Chain Dictionaries and generating sentences from those dictionaries.
11
11
  module MarkyMarkov
12
- VERSION = '0.1.2'
12
+ VERSION = '0.1.3'
13
13
 
14
14
  class TemporaryDictionary
15
15
  # Create a new Temporary Markov Chain Dictionary and sentence generator for use.
16
+ # Depth defaults to two words but can be set to any number between 1 and 9.
16
17
  #
17
18
  # @example Create a new Temporary Dictionary.
18
19
  # markov = MarkyMarkov::TemporaryDictionary.new
19
- # @return [Object] a MarkyMarkov::TemporaryDictionary object.
20
- def initialize
21
- @dictionary = TwoWordDictionary.new
22
- @sentence = TwoWordSentenceGenerator.new(@dictionary)
20
+ # @example Create a three word Temporary Dictionary.
21
+ # markov = MarkyMarkov::TemporaryDictionary.new(3)
22
+ # @param [Int] depth Optional dictionary depth. Defaults to 2.
23
+ # @return [Object] a MarkyMarkov::TemporaryDictionary object`.
24
+ def initialize(depth=2)
25
+ @dictionary = MarkovDictionary.new(depth)
26
+ @sentence = MarkovSentenceGenerator.new(@dictionary)
23
27
  end
24
28
 
25
29
  # Parses a given file and adds the sentences it contains to the current dictionary.
@@ -67,6 +71,7 @@ module MarkyMarkov
67
71
  end
68
72
  end
69
73
 
74
+ # @since 0.1.2
70
75
  # Modify respond_to? to include generate_n_words method_missing implementation.
71
76
  def respond_to?(method_sym, include_private = false)
72
77
  if method_sym.to_s =~ /^generate_(\d*)_word[s]*$/
@@ -89,15 +94,19 @@ module MarkyMarkov
89
94
 
90
95
  class Dictionary < TemporaryDictionary
91
96
  # Open (or create if it doesn't exist) a Persistent Markov Chain Dictionary
92
- # and sentence generator for use.
97
+ # and sentence generator for use. Optional dictionary depth may be supplied.
93
98
  #
94
99
  # @example Create a new Persistent Dictionary object.
95
100
  # markov = MarkyMarkov::Dictionary.new("#{ENV["HOME"]}/markov_dictionary")
101
+ # @example Create a new Persistent Dictionary object with a depth of 4.
102
+ # markov = MarkyMarkov::Dictionary.new('mmdict.mmd'. 4)
103
+ # @param [File] location The location the dictionary file is/will be stored.
104
+ # @param [Int] depth The depth of the dictionary. Defaults to 2.
96
105
  attr_reader :dictionarylocation
97
- def initialize(location)
106
+ def initialize(location, depth=2)
98
107
  @dictionarylocation = "#{location}.mmd"
99
- @dictionary = PersistentDictionary.new(@dictionarylocation)
100
- @sentence = TwoWordSentenceGenerator.new(@dictionary)
108
+ @dictionary = PersistentDictionary.new(@dictionarylocation, depth)
109
+ @sentence = MarkovSentenceGenerator.new(@dictionary)
101
110
  end
102
111
 
103
112
  # Save the Persistent Dictionary file into JSON format for later use.
@@ -120,7 +129,7 @@ module MarkyMarkov
120
129
  # MarkyMarkov::Dictionary.delete_dictionary!("#{ENV["HOME"]}/markov_dictionary")
121
130
  # @example Delete the dictionary of the object 'markov'
122
131
  # MarkyMarkov::Dictionary.delete_dictionary!(markov)
123
- # @param [String] location location/name of the dictionary file to be deleted.
132
+ # @param [String/Object] location location/name of the dictionary file to be deleted.
124
133
  def self.delete_dictionary!(location)
125
134
  location += ".mmd" if location.class == String
126
135
  PersistentDictionary.delete_dictionary!(location)
@@ -0,0 +1,76 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe MarkovDictionary do
4
+ context "One Word Depth Dictionary" do
5
+ before(:each) do
6
+ @onetextsource = "spec/test.txt"
7
+ @onedict = MarkovDictionary.new(1)
8
+ @onedict.parse_source("Hello how are you doing today", false)
9
+ @onestringdict = {"Hello" => {"how" => 1},
10
+ "how" => {"are" => 1},
11
+ "are" => {"you" => 1},
12
+ "you" => {"doing" => 1},
13
+ "doing" => {"today" => 1},
14
+ "today" => {} }
15
+ @onetextdict = {"The" => {"cat"=>1},
16
+ "and" => {"chainsaws"=>1},
17
+ "cat" => {"likes"=>1},
18
+ "chainsaws" => {},
19
+ "likes" => {"pie"=>1},
20
+ "pie" => {"and"=>1} }
21
+ end
22
+
23
+ it "can open a file" do
24
+ @onedict.open_source(@onetextsource).should_not be_nil
25
+ end
26
+
27
+ it "should give a FileNotFoundError if the file doesn't exist" do
28
+ expect { @onedict.open_source("thisisntreal") }.to
29
+ raise_error(MarkovDictionary::FileNotFoundError,"thisisntreal does not exist!")
30
+ end
31
+
32
+ it "can add a word to the dictionary" do
33
+ @onedict.add_word("to", "be")
34
+ @onedict.dictionary.should include("to" => {"be" => 1})
35
+ end
36
+
37
+ it "create a dictionary via parsing a text file" do
38
+ @onedict.dictionary = {}
39
+ @onedict.parse_source(@onetextsource)
40
+ @onedict.dictionary.should eql(@onetextdict)
41
+ end
42
+
43
+ it "builds a one word dictionary properly" do
44
+ @onedict.dictionary.should eql(@onestringdict)
45
+ end
46
+ end
47
+
48
+ context "Two Word Dictionary" do
49
+ before(:each) do
50
+ @twodict = MarkovDictionary.new
51
+ @twodict.parse_source("The cat likes pie and chainsaws", false)
52
+ @twotextsource = "spec/test.txt"
53
+ @twostringdict = { "The cat" => { "likes" => 1},
54
+ "cat likes" => { "pie" => 1 },
55
+ "likes pie" => {"and" => 1 },
56
+ "pie and" => { "chainsaws" => 1 },
57
+ "and chainsaws" => {} }
58
+ @twotextdict = {"The cat" => {"likes" => 1},
59
+ "cat likes" => {"pie" => 1},
60
+ "likes pie" => {"and" => 1},
61
+ "pie and" => {"chainsaws" => 1},
62
+ "and chainsaws" => {}}
63
+ end
64
+
65
+ it "can add a word to the two-word dictionary" do
66
+ @twodict.add_word("Zebras like", "kung-fu")
67
+ @twodict.dictionary.should eql(@twostringdict.merge( {"Zebras like" => {"kung-fu" => 1}} ))
68
+ end
69
+
70
+ it "create a two-word dictionary via parsing a text file" do
71
+ @twodict.dictionary = {}
72
+ @twodict.parse_source(@twotextsource)
73
+ @twodict.dictionary.should eql(@twotextdict)
74
+ end
75
+ end
76
+ end
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
- describe OneWordSentenceGenerator do
3
+ describe MarkovSentenceGenerator do
4
4
  before(:each) do
5
- @dict = OneWordDictionary.new
5
+ @dict = MarkovDictionary.new
6
6
  @dict.parse_source("Hello man how are you today", false)
7
- @sentence = OneWordSentenceGenerator.new(@dict)
7
+ @sentence = MarkovSentenceGenerator.new(@dict)
8
8
  end
9
9
 
10
10
  it "can pick a random word" do
@@ -1 +1 @@
1
- {"The cat":{"likes":1},"cat likes":{"pie":1},"likes pie":{"and":1},"pie and":{"chainsaws":1},"and chainsaws":{}}
1
+ 2{"The cat":{"likes":1},"cat likes":{"pie":1},"likes pie":{"and":1},"pie and":{"chainsaws":1},"and chainsaws":{}}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marky_markov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-07 00:00:00.000000000 Z
12
+ date: 2012-02-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby
16
- requirement: &70118059271520 !ruby/object:Gem::Requirement
16
+ requirement: &70361383496140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -24,7 +24,7 @@ dependencies:
24
24
  version: 2.0.0
25
25
  type: :runtime
26
26
  prerelease: false
27
- version_requirements: *70118059271520
27
+ version_requirements: *70361383496140
28
28
  description: ! "MarkyMarkov makes it easy to generate simply Markov Chains based upon
29
29
  input from\n either a source file or a string. While usable as a module in your
30
30
  code it can also be called on\n from the command line and piped into like a standard
@@ -39,16 +39,12 @@ files:
39
39
  - README.md
40
40
  - bin/marky_markov
41
41
  - lib/marky_markov.rb
42
- - lib/marky_markov/one_word_dictionary.rb
43
- - lib/marky_markov/one_word_sentence_generator.rb
42
+ - lib/marky_markov/markov_dictionary.rb
43
+ - lib/marky_markov/markov_sentence_generator.rb
44
44
  - lib/marky_markov/persistent_dictionary.rb
45
- - lib/marky_markov/two_word_dictionary.rb
46
- - lib/marky_markov/two_word_sentence_generator.rb
47
- - spec/marky_markov/one_word_dictionary_spec.rb
48
- - spec/marky_markov/one_word_sentence_spec.rb
45
+ - spec/marky_markov/markov_dictionary_spec.rb
46
+ - spec/marky_markov/markov_sentence_generator_spec.rb
49
47
  - spec/marky_markov/persistent_dictionary_spec.rb
50
- - spec/marky_markov/two_word_dict_spec.rb
51
- - spec/marky_markov/two_word_sentence_spec.rb
52
48
  - spec/spec_helper.rb
53
49
  - spec/textdictcompare.mmd
54
50
  homepage: http://www.thefurd.com
@@ -1,19 +0,0 @@
1
- require_relative 'one_word_dictionary'
2
-
3
- # @private
4
- class TwoWordDictionary < OneWordDictionary
5
- # Given a source of text, be it a text file (file=true) or a string (file=false)
6
- # it will add all the words within the source to the markov dictionary.
7
- #
8
- # @example Add a text file
9
- # parse_source("text.txt")
10
- # @example Add a string
11
- # parse_source("Hi, how are you doing?", false)
12
- def parse_source(source, file=true)
13
- contents = file ? open_source(source) : contents = source.split
14
- contents.each_cons(3) do |first, second, third|
15
- self.add_word("#{first} #{second}", third)
16
- end
17
- @dictionary[contents.last(2).join(' ')] ||= Hash.new(0)
18
- end
19
- end
@@ -1,14 +0,0 @@
1
- require_relative 'one_word_sentence_generator'
2
-
3
- # @private
4
- class TwoWordSentenceGenerator < OneWordSentenceGenerator
5
- def generate(wordcount)
6
- sentence = []
7
- sentence.concat(random_word.split)
8
- (wordcount-1).times do
9
- sentence.concat(weighted_random(sentence.last(2).join(' ')).split)
10
- end
11
- sentence.pop(sentence.length-wordcount)
12
- sentence.join(' ')
13
- end
14
- end
@@ -1,45 +0,0 @@
1
- require 'spec_helper.rb'
2
-
3
- describe OneWordDictionary do
4
- before(:each) do
5
- @textsource = "spec/test.txt"
6
- @dict = OneWordDictionary.new
7
- @dict.parse_source("Hello how are you doing today", false)
8
- @stringdict = {"Hello" => {"how" => 1},
9
- "how" => {"are" => 1},
10
- "are" => {"you" => 1},
11
- "you" => {"doing" => 1},
12
- "doing" => {"today" => 1},
13
- "today" => {} }
14
- @textdict = {"The" => {"cat"=>1},
15
- "and" => {"chainsaws"=>1},
16
- "cat" => {"likes"=>1},
17
- "chainsaws" => {},
18
- "likes" => {"pie"=>1},
19
- "pie" => {"and"=>1} }
20
- end
21
-
22
- it "can open a file" do
23
- @dict.open_source(@textsource).should_not be_nil
24
- end
25
-
26
- it "should give a FileNotFoundError if the file doesn't exist" do
27
- expect { @dict.open_source("thisisntreal") }.to
28
- raise_error(OneWordDictionary::FileNotFoundError,"thisisntreal does not exist!")
29
- end
30
-
31
- it "can add a word to the dictionary" do
32
- @dict.add_word("to", "be")
33
- @dict.dictionary.should include("to" => {"be" => 1})
34
- end
35
-
36
- it "create a dictionary via parsing a text file" do
37
- @dict.dictionary = {}
38
- @dict.parse_source(@textsource)
39
- @dict.dictionary.should eql(@textdict)
40
- end
41
-
42
- it "builds a one word dictionary properly" do
43
- @dict.dictionary.should eql(@stringdict)
44
- end
45
- end
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe TwoWordDictionary do
4
- before(:each) do
5
- @dict = TwoWordDictionary.new
6
- @dict.parse_source("The cat likes pie and chainsaws", false)
7
- @textsource = "spec/test.txt"
8
- @stringdict = { "The cat" => { "likes" => 1},
9
- "cat likes" => { "pie" => 1 },
10
- "likes pie" => {"and" => 1 },
11
- "pie and" => { "chainsaws" => 1 },
12
- "and chainsaws" => {} }
13
- @textdict = {"The cat" => {"likes" => 1},
14
- "cat likes" => {"pie" => 1},
15
- "likes pie" => {"and" => 1},
16
- "pie and" => {"chainsaws" => 1},
17
- "and chainsaws" => {}}
18
- end
19
-
20
- it "can add a word to the two-word dictionary" do
21
- @dict.add_word("Zebras like", "kung-fu")
22
- @dict.dictionary.should eql(@stringdict.merge( {"Zebras like" => {"kung-fu" => 1}} ))
23
- end
24
-
25
- it "create a two-word dictionary via parsing a text file" do
26
- @dict.dictionary = {}
27
- @dict.parse_source(@textsource)
28
- @dict.dictionary.should eql(@textdict)
29
- end
30
- end
31
-
@@ -1,13 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe TwoWordSentenceGenerator do
4
- before(:each) do
5
- @dict = TwoWordDictionary.new
6
- @dict.parse_source("Hello man how are you today", false)
7
- @sentence = TwoWordSentenceGenerator.new(@dict)
8
- end
9
-
10
- it "generates a sentence of the appropriate length" do
11
- @sentence.generate(20).split.count.should eql(20)
12
- end
13
- end