memorable_strings 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +25 -0
- data/LICENSE +15 -0
- data/README.rdoc +49 -0
- data/Rakefile +88 -0
- data/init.rb +1 -0
- data/lib/memorable_strings/consonant.rb +21 -0
- data/lib/memorable_strings/digit.rb +18 -0
- data/lib/memorable_strings/extensions/string.rb +91 -0
- data/lib/memorable_strings/phoneme.rb +116 -0
- data/lib/memorable_strings/vowel.rb +29 -0
- data/lib/memorable_strings.rb +5 -0
- data/test/consonant_test.rb +26 -0
- data/test/digit_test.rb +41 -0
- data/test/phoneme_test.rb +220 -0
- data/test/string_test.rb +234 -0
- data/test/test_helper.rb +31 -0
- data/test/vowel_test.rb +92 -0
- metadata +75 -0
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
== master
|
2
|
+
|
3
|
+
== 0.1.0 / 2009-04-18
|
4
|
+
|
5
|
+
* Add :print_friendly option to skip ambiguous characters [Nate Kontny]
|
6
|
+
* Add better tests
|
7
|
+
* Add more documentation
|
8
|
+
* Redesign phoneme / consonant / vowel / digit logic to be in separate classes
|
9
|
+
* Move Password.generate to String.memorable
|
10
|
+
* Rename to memorable_strings
|
11
|
+
|
12
|
+
== 0.0.3 / 2009-01-11
|
13
|
+
|
14
|
+
* Add compatibility with Ruby 1.9+
|
15
|
+
|
16
|
+
== 0.0.2 / 2008-05-05
|
17
|
+
|
18
|
+
* Update documentation
|
19
|
+
|
20
|
+
== 0.0.1 / 2007-09-26
|
21
|
+
|
22
|
+
* Add documentation
|
23
|
+
* Fix licensing
|
24
|
+
* Add unit tests
|
25
|
+
* Rename to password_generator
|
data/LICENSE
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Copyright (C) 2002-2006 Ian Macdonald, 2006-2009 Aaron Pfeifer
|
2
|
+
|
3
|
+
This program is free software; you can redistribute it and/or modify
|
4
|
+
it under the terms of the GNU General Public License as published by
|
5
|
+
the Free Software Foundation; either version 2, or (at your option)
|
6
|
+
any later version.
|
7
|
+
|
8
|
+
This program is distributed in the hope that it will be useful,
|
9
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
GNU General Public License for more details.
|
12
|
+
|
13
|
+
You should have received a copy of the GNU General Public License
|
14
|
+
along with this program; if not, write to the Free Software Foundation,
|
15
|
+
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
data/README.rdoc
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
= memorable_strings
|
2
|
+
|
3
|
+
+memorable_strings+ generates strings that can be easily remembered.
|
4
|
+
|
5
|
+
== Resources
|
6
|
+
|
7
|
+
API
|
8
|
+
|
9
|
+
* http://api.pluginaweek.org/memorable_strings
|
10
|
+
|
11
|
+
Bugs
|
12
|
+
|
13
|
+
* http://pluginaweek.lighthouseapp.com/projects/13282-memorable_strings
|
14
|
+
|
15
|
+
Development
|
16
|
+
|
17
|
+
* http://github.com/pluginaweek/memorable_strings
|
18
|
+
|
19
|
+
Source
|
20
|
+
|
21
|
+
* git://github.com/pluginaweek/memorable_strings.git
|
22
|
+
|
23
|
+
== Description
|
24
|
+
|
25
|
+
Certain strings like passwords are often difficult to remember, especially if
|
26
|
+
they are simply a random combination of letters and numbers. With
|
27
|
+
+memorable_strings+, strings are generated based on a set of rules that
|
28
|
+
combine phonemes in a manner that makes the sequence of characters more
|
29
|
+
memorable. When used in combination with features like generating passwords,
|
30
|
+
this can help improve the user experience.
|
31
|
+
|
32
|
+
== Usage
|
33
|
+
|
34
|
+
String.memorable # => "maikipeo"
|
35
|
+
String.memorable(:length => 5) # => "quoge"
|
36
|
+
String.memorable(:capital => true) # => "Bukievai"
|
37
|
+
String.memorable(:digit => true) # => "ood4yosa"
|
38
|
+
String.memorable(:capital => true, :digit => true) # => "Goodah5e"
|
39
|
+
String.memorable(:print_friendly => true) # => "ahkeehav"
|
40
|
+
|
41
|
+
See MemorableStrings::Extensions::String for more information.
|
42
|
+
|
43
|
+
== Dependencies
|
44
|
+
|
45
|
+
None.
|
46
|
+
|
47
|
+
== References
|
48
|
+
|
49
|
+
* Ian Macdonald - {ruby-password}[http://raa.ruby-lang.org/project/ruby-password]
|
data/Rakefile
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/contrib/sshpublisher'
|
5
|
+
|
6
|
+
spec = Gem::Specification.new do |s|
|
7
|
+
s.name = 'memorable_strings'
|
8
|
+
s.version = '0.1.0'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'Generates strings that can be easily remembered'
|
11
|
+
|
12
|
+
s.files = FileList['{lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc)
|
13
|
+
s.require_path = 'lib'
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.test_files = Dir['test/**/*_test.rb']
|
16
|
+
|
17
|
+
s.author = 'Aaron Pfeifer'
|
18
|
+
s.email = 'aaron@pluginaweek.org'
|
19
|
+
s.homepage = 'http://www.pluginaweek.org'
|
20
|
+
s.rubyforge_project = 'pluginaweek'
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Default: run all tests.'
|
24
|
+
task :default => :test
|
25
|
+
|
26
|
+
desc "Test the #{spec.name} plugin."
|
27
|
+
Rake::TestTask.new(:test) do |t|
|
28
|
+
t.libs << 'lib'
|
29
|
+
t.test_files = spec.test_files
|
30
|
+
t.verbose = true
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
require 'rcov/rcovtask'
|
35
|
+
namespace :test do
|
36
|
+
desc "Test the #{spec.name} plugin with Rcov."
|
37
|
+
Rcov::RcovTask.new(:rcov) do |t|
|
38
|
+
t.libs << 'lib'
|
39
|
+
t.test_files = spec.test_files
|
40
|
+
t.rcov_opts << '--exclude="^(?!lib/)"'
|
41
|
+
t.verbose = true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
rescue LoadError
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Generate documentation for the #{spec.name} plugin."
|
48
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = spec.name
|
51
|
+
rdoc.template = '../rdoc_template.rb'
|
52
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
53
|
+
rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG.rdoc', 'LICENSE', 'lib/**/*.rb')
|
54
|
+
end
|
55
|
+
|
56
|
+
Rake::GemPackageTask.new(spec) do |p|
|
57
|
+
p.gem_spec = spec
|
58
|
+
p.need_tar = true
|
59
|
+
p.need_zip = true
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'Publish the beta gem.'
|
63
|
+
task :pgem => [:package] do
|
64
|
+
Rake::SshFilePublisher.new('aaron@pluginaweek.org', '/home/aaron/gems.pluginaweek.org/public/gems', 'pkg', "#{spec.name}-#{spec.version}.gem").upload
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'Publish the API documentation.'
|
68
|
+
task :pdoc => [:rdoc] do
|
69
|
+
Rake::SshDirPublisher.new('aaron@pluginaweek.org', "/home/aaron/api.pluginaweek.org/public/#{spec.name}", 'rdoc').upload
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'Publish the API docs and gem'
|
73
|
+
task :publish => [:pgem, :pdoc, :release]
|
74
|
+
|
75
|
+
desc 'Publish the release files to RubyForge.'
|
76
|
+
task :release => [:gem, :package] do
|
77
|
+
require 'rubyforge'
|
78
|
+
|
79
|
+
ruby_forge = RubyForge.new.configure
|
80
|
+
ruby_forge.login
|
81
|
+
|
82
|
+
%w(gem tgz zip).each do |ext|
|
83
|
+
file = "pkg/#{spec.name}-#{spec.version}.#{ext}"
|
84
|
+
puts "Releasing #{File.basename(file)}..."
|
85
|
+
|
86
|
+
ruby_forge.add_release(spec.rubyforge_project, spec.name, spec.version, file)
|
87
|
+
end
|
88
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'memorable_strings'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'memorable_strings/phoneme'
|
2
|
+
|
3
|
+
module MemorableStrings
|
4
|
+
# Represents a phoneme that begins with a consonant letter
|
5
|
+
class Consonant < Phoneme
|
6
|
+
# Generates a phoneme of at most the given length that should follow this
|
7
|
+
# consononant.
|
8
|
+
#
|
9
|
+
# This will always generate a vowel.
|
10
|
+
def next(stack, maxlength, &block)
|
11
|
+
Vowel.random(maxlength, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Bootstrap
|
15
|
+
add %w(c f h j k m n p r t v w x y ch ph th)
|
16
|
+
add %w(b d g q s z qu sh), :print_friendly => :downcase
|
17
|
+
add :l, :print_friendly => false
|
18
|
+
add :ng, :first => false
|
19
|
+
add :gh, :first => false, :print_friendly => :downcase
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'memorable_strings/phoneme'
|
2
|
+
|
3
|
+
module MemorableStrings
|
4
|
+
# Represents a single-digit character
|
5
|
+
class Digit < Phoneme
|
6
|
+
# Generates a phoneme of at most the given length that should follow this
|
7
|
+
# digit.
|
8
|
+
#
|
9
|
+
# This will always randomly generate either a vowel or a consonant.
|
10
|
+
def next(stack, maxlength, &block)
|
11
|
+
Phoneme.first(maxlength, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Bootstrap
|
15
|
+
add %w(3 4 7 9)
|
16
|
+
add %w(0 1 2 5 6 8), :print_friendly => false
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'memorable_strings/phoneme'
|
2
|
+
require 'memorable_strings/digit'
|
3
|
+
require 'memorable_strings/vowel'
|
4
|
+
require 'memorable_strings/consonant'
|
5
|
+
|
6
|
+
module MemorableStrings
|
7
|
+
module Extensions #:nodoc:
|
8
|
+
# Adds support for easily generating memorable strings
|
9
|
+
module String
|
10
|
+
# Generates a string based on a set of rules defining which characters
|
11
|
+
# should be grouped together to form a memorable sequence.
|
12
|
+
#
|
13
|
+
# Configuration options:
|
14
|
+
# * <tt>:length</tt> - The length of the string to generate. Default is 8.
|
15
|
+
# * <tt>:capital</tt> - Whether to include a capital letter. Default is false.
|
16
|
+
# * <tt>:digit</tt> - Whether to include a digit. Default is false.
|
17
|
+
# * <tt>:print_friendly</tt> - Whether to only include characters that
|
18
|
+
# are unambiguous when printed out. This includes: B8G6I1l0OQDS5Z2
|
19
|
+
#
|
20
|
+
# == Examples
|
21
|
+
#
|
22
|
+
# String.memorable # => "maikipeo"
|
23
|
+
# String.memorable(:length => 5) # => "quoge"
|
24
|
+
# String.memorable(:capital => true) # => "Bukievai"
|
25
|
+
# String.memorable(:digit => true) # => "ood4yosa"
|
26
|
+
# String.memorable(:capital => true, :digit => true) # => "Goodah5e"
|
27
|
+
#
|
28
|
+
# == Algorithm
|
29
|
+
#
|
30
|
+
# See MemorableStrings::Consonant, MemorableStrings::Vowel, and
|
31
|
+
# MemorableStrings::Digit for more information about how it's determined
|
32
|
+
# which characters are allowed to follow which other characters.
|
33
|
+
def memorable(options = {})
|
34
|
+
invalid_keys = options.keys - [:length, :capital, :digit, :print_friendly]
|
35
|
+
raise ArgumentError, "Invalid key(s): #{invalid_keys.join(', ')}" unless invalid_keys.empty?
|
36
|
+
|
37
|
+
length = options[:length] || 8
|
38
|
+
raise ArgumentError, 'Length must be at least 1' if length < 1
|
39
|
+
raise ArgumentError, 'Length must be at least 3 if using digits' if length < 3 && options[:digit]
|
40
|
+
|
41
|
+
value = nil
|
42
|
+
conditions = lambda {|phoneme| options[:print_friendly] ? phoneme.print_friendly?(:downcase) : true}
|
43
|
+
|
44
|
+
begin
|
45
|
+
value = ''
|
46
|
+
stack = []
|
47
|
+
left = length
|
48
|
+
flags = options.dup
|
49
|
+
phoneme = nil
|
50
|
+
|
51
|
+
begin
|
52
|
+
if !phoneme
|
53
|
+
# Special-case first
|
54
|
+
phoneme = Phoneme.first(left, &conditions)
|
55
|
+
elsif flags[:digit] && stack.length >= 2 && rand(10) < 3
|
56
|
+
# Add digit in >= 3rd spot (30% chance)
|
57
|
+
flags.delete(:digit)
|
58
|
+
phoneme = Digit.random(1, &conditions)
|
59
|
+
else
|
60
|
+
# Choose next based on current phoneme
|
61
|
+
phoneme = phoneme.next(stack, left, &conditions)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Track the phoneme
|
65
|
+
stack << phoneme
|
66
|
+
value << phoneme.value
|
67
|
+
left -= phoneme.length
|
68
|
+
|
69
|
+
# Capitalize the first letter, phoneme after or a digit, or a consonant (30% chance)
|
70
|
+
if flags[:capital]
|
71
|
+
previous = stack[-2]
|
72
|
+
upcase_allowed = !options[:print_friendly] || phoneme.print_friendly?(:upcase)
|
73
|
+
context_allowed = !previous || previous.is_a?(Digit) || phoneme.is_a?(Consonant)
|
74
|
+
|
75
|
+
if upcase_allowed && context_allowed && rand(10) < 3
|
76
|
+
flags.delete(:capital)
|
77
|
+
value[-phoneme.length, 1] = value[-phoneme.length, 1].upcase!
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end while left > 0
|
81
|
+
end while [:capital, :digit].any? {|key| flags.include?(key)}
|
82
|
+
|
83
|
+
value
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
String.class_eval do
|
90
|
+
extend MemorableStrings::Extensions::String
|
91
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module MemorableStrings
|
2
|
+
# A unit of sound that can be used to build a larger string. Phonemes have
|
3
|
+
# no semantic meaning themselves, but have sound types and characteristics
|
4
|
+
# associated with them that are helpful in building a discernable word.
|
5
|
+
class Phoneme
|
6
|
+
class << self
|
7
|
+
# The collection of phonemes
|
8
|
+
attr_reader :all
|
9
|
+
|
10
|
+
# Adds a new phoneme of the current class's type.
|
11
|
+
#
|
12
|
+
# See Phoneme#new for more information.
|
13
|
+
def add(*values)
|
14
|
+
options = values.last.is_a?(Hash) ? values.pop : {}
|
15
|
+
|
16
|
+
values.flatten!
|
17
|
+
values.map! do |value|
|
18
|
+
(@all ||= []) << value = new(value, options)
|
19
|
+
value
|
20
|
+
end
|
21
|
+
values.length == 1 ? values.first : values
|
22
|
+
end
|
23
|
+
|
24
|
+
# Generates a random phoneme for the current class of at most the given
|
25
|
+
# length. In addition, an optional block can be used to determine
|
26
|
+
# whether the chosen phoneme is acceptable.
|
27
|
+
#
|
28
|
+
# == Examples
|
29
|
+
#
|
30
|
+
# # Choose any vowel
|
31
|
+
# MemorableStrings::Vowel.random
|
32
|
+
# # => #<MemorableStrings::Vowel:0xb7c3efe4 @first=true, @value="e", @length=1>
|
33
|
+
#
|
34
|
+
# # Choose a vowel with at most 1 character
|
35
|
+
# MemorableStrings::Vowel.random(2)
|
36
|
+
# # => <MemorableStrings::Vowel:0xb7c3eb34 @first=true, @value="u", @length=1>
|
37
|
+
#
|
38
|
+
# # Choose a vowel that can be the first letter
|
39
|
+
# MemorableStrings::Vowel.random {|vowel| vowel.first?}
|
40
|
+
# # => #<MemorableStrings::Vowel:0xb7c3e080 @first=true, @value="a", @length=1>
|
41
|
+
def random(maxlength = nil, &block)
|
42
|
+
phonemes = all
|
43
|
+
phonemes = phonemes.select {|phoneme| phoneme.length <= maxlength} if maxlength
|
44
|
+
|
45
|
+
begin
|
46
|
+
phoneme = phonemes[rand(phonemes.size)]
|
47
|
+
end while !phoneme.matches?(&block)
|
48
|
+
|
49
|
+
phoneme
|
50
|
+
end
|
51
|
+
|
52
|
+
# Generates a random phoneme of at most the given length. This will
|
53
|
+
# only randomly choose from the following sounds that are allowed to be
|
54
|
+
# the first character:
|
55
|
+
# * Vowel
|
56
|
+
# * Consonant
|
57
|
+
#
|
58
|
+
# == Examples
|
59
|
+
#
|
60
|
+
# MemorableStrings::Phoneme.first(1)
|
61
|
+
# #<MemorableStrings::Consonant:0xb7c38248 @first=true, @value="x", @length=1>
|
62
|
+
#
|
63
|
+
# MemorableStrings::Phoneme.first(2)
|
64
|
+
# #<MemorableStrings::Vowel:0xb7c3e2b0 @first=true, @value="ae", @length=2>
|
65
|
+
def first(maxlength, &block)
|
66
|
+
(rand(2) == 1 ? Vowel : Consonant).random(maxlength) do |phoneme|
|
67
|
+
phoneme.first? && phoneme.matches?(&block)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# The character(s) representing this phoneme
|
73
|
+
attr_reader :value
|
74
|
+
|
75
|
+
# The number of characters
|
76
|
+
attr_reader :length
|
77
|
+
|
78
|
+
# Creates a new phoneme with the given value and configuration options.
|
79
|
+
#
|
80
|
+
# Configuration options:
|
81
|
+
# * <tt>:first</strong> - Whether it can be used as the first value in a
|
82
|
+
# string. Default is true.
|
83
|
+
# * <tt>:print_friendly</strong> - Whether the characters are unambiguous
|
84
|
+
# when printed. This can be set to one of the following values:
|
85
|
+
# * <tt>true</tt> - Always print-friendly (default)
|
86
|
+
# * <tt>:downcase</tt> - Only print-friendly when in lower case
|
87
|
+
# * <tt>:upcase</tt> - Only print-friendly when in upper case
|
88
|
+
# * <tt>false</tt> - Never print-friendly
|
89
|
+
def initialize(value, options = {})
|
90
|
+
invalid_keys = options.keys - [:first, :print_friendly]
|
91
|
+
raise ArgumentError, "Invalid key(s): #{invalid_keys.join(', ')}" unless invalid_keys.empty?
|
92
|
+
|
93
|
+
options = {:first => true, :print_friendly => true}.merge(options)
|
94
|
+
|
95
|
+
@value = value.to_s
|
96
|
+
@length = @value.length
|
97
|
+
@first = options[:first]
|
98
|
+
@print_friendly = options[:print_friendly]
|
99
|
+
end
|
100
|
+
|
101
|
+
# Is this allowed to be the first in a sequence of phonemes?
|
102
|
+
def first?
|
103
|
+
@first
|
104
|
+
end
|
105
|
+
|
106
|
+
# Is this character unambiguous with other characters?
|
107
|
+
def print_friendly?(context)
|
108
|
+
@print_friendly == true || @print_friendly == context
|
109
|
+
end
|
110
|
+
|
111
|
+
# Does this phoneme match the conditions specified by the block?
|
112
|
+
def matches?
|
113
|
+
!block_given? || yield(self)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'memorable_strings/phoneme'
|
2
|
+
|
3
|
+
module MemorableStrings
|
4
|
+
# Represents a phoneme that begins with a vowel letter
|
5
|
+
class Vowel < Phoneme
|
6
|
+
# Generates a phoneme of at most the given length that should follow this
|
7
|
+
# vowel.
|
8
|
+
#
|
9
|
+
# If the last two characters in the stack (including this one) were
|
10
|
+
# vowels, then this will always generate a consonant. Otherwise, 40% of
|
11
|
+
# the time it will generate a single-character vowel and 60% of the time
|
12
|
+
# it will generate a consonant.
|
13
|
+
#
|
14
|
+
# It is never possible for two consecutive vowel phonemes to result in
|
15
|
+
# more than 2 vowel characters in the stack.
|
16
|
+
def next(stack, maxlength, &block)
|
17
|
+
previous = stack[-2]
|
18
|
+
if previous && previous.is_a?(Vowel) || length > 1 || rand(10) > 3
|
19
|
+
Consonant.random(1, &block)
|
20
|
+
else
|
21
|
+
Vowel.random(1, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Bootstrap
|
26
|
+
add %w(a e u ae ah ee)
|
27
|
+
add %w(i o ai ei ie oh oo), :print_friendly => false
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ConsonantNextTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
setup_phonemes
|
6
|
+
|
7
|
+
MemorableStrings::Vowel.all << @a = MemorableStrings::Vowel.new(:a)
|
8
|
+
@b = MemorableStrings::Consonant.new(:b)
|
9
|
+
@stack = [@b]
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_generate_a_vowel
|
13
|
+
assert_equal @a, @b.next(@stack, 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_allow_block_conditional
|
17
|
+
MemorableStrings::Vowel.all << @c = MemorableStrings::Vowel.new(:c)
|
18
|
+
MemorableStrings::Vowel.expects(:rand).with(2).times(2).returns(1, 0)
|
19
|
+
|
20
|
+
assert_equal @a, @b.next(@stack, 2) {|phoneme| phoneme.value == 'a'}
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
teardown_phonemes
|
25
|
+
end
|
26
|
+
end
|
data/test/digit_test.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class DigitNextTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
setup_phonemes
|
6
|
+
|
7
|
+
@digit = MemorableStrings::Digit.new(1)
|
8
|
+
@stack = [@digit]
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_should_generate_vowel_half_the_time
|
12
|
+
MemorableStrings::Vowel.all << @a = MemorableStrings::Vowel.new(:a)
|
13
|
+
|
14
|
+
MemorableStrings::Vowel.expects(:rand).at_least_once.returns(0)
|
15
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(1)
|
16
|
+
|
17
|
+
assert_equal @a, @digit.next(@stack, 2)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_generate_consonant_half_the_time
|
21
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Vowel.new(:b)
|
22
|
+
|
23
|
+
MemorableStrings::Consonant.expects(:rand).at_least_once.returns(0)
|
24
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(0)
|
25
|
+
|
26
|
+
assert_equal @b, @digit.next(@stack, 2)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_allow_block_conditional
|
30
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Vowel.new(:b)
|
31
|
+
MemorableStrings::Consonant.all << @c = MemorableStrings::Vowel.new(:c)
|
32
|
+
MemorableStrings::Consonant.expects(:rand).with(2).times(2).returns(1, 0)
|
33
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(0)
|
34
|
+
|
35
|
+
assert_equal @b, @digit.next(@stack, 2) {|phoneme| phoneme.value == 'b'}
|
36
|
+
end
|
37
|
+
|
38
|
+
def teardown
|
39
|
+
teardown_phonemes
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class PhonemeByDefaultTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@phoneme = MemorableStrings::Phoneme.new(:a)
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_have_a_value
|
9
|
+
assert_equal 'a', @phoneme.value
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_have_a_length
|
13
|
+
assert_equal 1, @phoneme.length
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_be_allowed_to_be_first
|
17
|
+
assert @phoneme.first?
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_be_print_friendly_with_downcase_context
|
21
|
+
assert @phoneme.print_friendly?(:downcase)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_should_be_print_friendly_with_upcase_context
|
25
|
+
assert @phoneme.print_friendly?(:upcase)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class PhonemeTest < Test::Unit::TestCase
|
30
|
+
def test_should_raise_exception_if_invalid_option_specified
|
31
|
+
assert_raise(ArgumentError) { MemorableStrings::Phoneme.new(:a, :invalid => true) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class PhonemeWithMultipleCharactersTest < Test::Unit::TestCase
|
36
|
+
def setup
|
37
|
+
@phoneme = MemorableStrings::Phoneme.new(:ab)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_should_have_a_value
|
41
|
+
assert_equal 'ab', @phoneme.value
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_have_a_length
|
45
|
+
assert_equal 2, @phoneme.length
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_should_be_allowed_to_be_first
|
49
|
+
assert @phoneme.first?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class PhonemeNotFirstTest < Test::Unit::TestCase
|
54
|
+
def setup
|
55
|
+
@phoneme = MemorableStrings::Phoneme.new(:a, :first => false)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_should_not_be_allowed_to_be_first
|
59
|
+
assert !@phoneme.first?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class PhonemeNotPrintFriendlyTest < Test::Unit::TestCase
|
64
|
+
def setup
|
65
|
+
@phoneme = MemorableStrings::Phoneme.new(:i, :print_friendly => false)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_not_be_print_friendly_with_downcase_context
|
69
|
+
assert !@phoneme.print_friendly?(:downcase)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_should_not_be_print_friendly_with_upcase_context
|
73
|
+
assert !@phoneme.print_friendly?(:upcase)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class PhonemeContextPrintFriendlyTest < Test::Unit::TestCase
|
78
|
+
def setup
|
79
|
+
@phoneme = MemorableStrings::Phoneme.new(:b, :print_friendly => :downcase)
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_should_be_print_friendly_with_downcase_context
|
83
|
+
assert @phoneme.print_friendly?(:downcase)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_should_not_be_print_friendly_with_upcase_context
|
87
|
+
assert !@phoneme.print_friendly?(:upcase)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class PhonemeMatchingTest < Test::Unit::TestCase
|
92
|
+
def setup
|
93
|
+
@phoneme = MemorableStrings::Phoneme.new(:a)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_should_match_if_no_block_given
|
97
|
+
assert @phoneme.matches?
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_should_pass_self_into_block
|
101
|
+
context = nil
|
102
|
+
@phoneme.matches? {|*args| context = args}
|
103
|
+
|
104
|
+
assert_equal [@phoneme], context
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_should_match_if_block_is_not_false
|
108
|
+
assert @phoneme.matches? {true}
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_should_not_match_if_block_is_false
|
112
|
+
assert !@phoneme.matches? {false}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class PhonemeCreationTest < Test::Unit::TestCase
|
117
|
+
def test_should_add_phoneme_to_collection
|
118
|
+
phoneme = MemorableStrings::Phoneme.add(:a)
|
119
|
+
|
120
|
+
assert_equal [phoneme], MemorableStrings::Phoneme.all
|
121
|
+
assert_equal 'a', phoneme.value
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_should_allow_multiple_phonemes
|
125
|
+
phonemes = MemorableStrings::Phoneme.add(:a, :b, :c, :first => false)
|
126
|
+
|
127
|
+
assert_equal 3, phonemes.length
|
128
|
+
assert_equal phonemes, MemorableStrings::Phoneme.all
|
129
|
+
assert phonemes.all? {|phoneme| !phoneme.first?}
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_should_allow_phoneme_arraye
|
133
|
+
phonemes = MemorableStrings::Phoneme.add([:a, :b, :c], :first => false)
|
134
|
+
|
135
|
+
assert_equal 3, phonemes.length
|
136
|
+
assert_equal phonemes, MemorableStrings::Phoneme.all
|
137
|
+
assert phonemes.all? {|phoneme| !phoneme.first?}
|
138
|
+
end
|
139
|
+
|
140
|
+
def teardown
|
141
|
+
MemorableStrings::Phoneme.all.clear
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class PhonemeRandomTest < Test::Unit::TestCase
|
146
|
+
def setup
|
147
|
+
@a, @b, @ab = MemorableStrings::Phoneme.add(:a, :b, :ab)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_should_select_any_phoneme
|
151
|
+
MemorableStrings::Phoneme.expects(:rand).with(3).returns(0)
|
152
|
+
assert_equal @a, MemorableStrings::Phoneme.random
|
153
|
+
|
154
|
+
MemorableStrings::Phoneme.expects(:rand).with(3).returns(1)
|
155
|
+
assert_equal @b, MemorableStrings::Phoneme.random
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_should_restrict_selection_based_on_maxlength
|
159
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(0)
|
160
|
+
assert_equal @a, MemorableStrings::Phoneme.random(1)
|
161
|
+
end
|
162
|
+
|
163
|
+
def teardown
|
164
|
+
MemorableStrings::Phoneme.all.clear
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class PhonemeRandomWithBlockTest < Test::Unit::TestCase
|
169
|
+
def setup
|
170
|
+
@a, @b = MemorableStrings::Phoneme.add(:a, :b)
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_should_select_phoneme_that_returns_true
|
174
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(0)
|
175
|
+
assert_equal @a, MemorableStrings::Phoneme.random {|phoneme| phoneme.value == 'a'}
|
176
|
+
|
177
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).times(2).returns(1, 0)
|
178
|
+
assert_equal @a, MemorableStrings::Phoneme.random {|phoneme| phoneme.value == 'a'}
|
179
|
+
end
|
180
|
+
|
181
|
+
def teardown
|
182
|
+
MemorableStrings::Phoneme.all.clear
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class PhonemeFirstTest < Test::Unit::TestCase
|
187
|
+
def setup
|
188
|
+
setup_phonemes
|
189
|
+
|
190
|
+
MemorableStrings::Vowel.all << @a = MemorableStrings::Vowel.new(:a)
|
191
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Consonant.new(:b)
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_should_select_vowel_half_the_time
|
195
|
+
MemorableStrings::Vowel.expects(:rand).with(1).returns(0)
|
196
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(1)
|
197
|
+
|
198
|
+
assert_equal @a, MemorableStrings::Phoneme.first(1)
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_should_select_consonant_half_the_time
|
202
|
+
MemorableStrings::Consonant.expects(:rand).with(1).returns(0)
|
203
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(0)
|
204
|
+
|
205
|
+
assert_equal @b, MemorableStrings::Phoneme.first(1)
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_should_not_select_phonemes_marked_as_not_first
|
209
|
+
c = MemorableStrings::Consonant.add(:c, :first => false)
|
210
|
+
|
211
|
+
MemorableStrings::Consonant.expects(:rand).with(2).times(2).returns(1, 0)
|
212
|
+
MemorableStrings::Phoneme.expects(:rand).with(2).returns(0)
|
213
|
+
|
214
|
+
assert_equal @b, MemorableStrings::Phoneme.first(1)
|
215
|
+
end
|
216
|
+
|
217
|
+
def teardown
|
218
|
+
teardown_phonemes
|
219
|
+
end
|
220
|
+
end
|
data/test/string_test.rb
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class StringByDefaultTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@value = String.memorable
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_should_have_8_characters
|
9
|
+
assert_equal 8, @value.length
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_not_include_capital_letter
|
13
|
+
assert_no_match /[A-Z]/, @value
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_should_not_include_digit
|
17
|
+
assert_no_match /[0-9]/, @value
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_should_be_consistent
|
21
|
+
consistent = (1..1000).each do
|
22
|
+
value = String.memorable
|
23
|
+
value =~ /^[a-z]+$/
|
24
|
+
end
|
25
|
+
|
26
|
+
assert consistent
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class StringTest < Test::Unit::TestCase
|
31
|
+
def test_should_raise_exception_if_invalid_option_specified
|
32
|
+
assert_raise(ArgumentError) { String.memorable(:invalid => true) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_should_raise_exception_if_invalid_length
|
36
|
+
assert_raise(ArgumentError) { String.memorable(:length => -1) }
|
37
|
+
assert_raise(ArgumentError) { String.memorable(:length => 0) }
|
38
|
+
assert_nothing_raised { String.memorable(:length => 1) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_raise_exception_if_length_too_short_with_digits
|
42
|
+
assert_raise(ArgumentError) { String.memorable(:length => 1, :digit => true) }
|
43
|
+
assert_raise(ArgumentError) { String.memorable(:length => 2, :digit => true) }
|
44
|
+
assert_nothing_raised { String.memorable(:length => 3, :digit => true) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class StringWithCustomLengthTest < Test::Unit::TestCase
|
49
|
+
def setup
|
50
|
+
@value = String.memorable(:length => 2)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_should_use_custom_length
|
54
|
+
assert_equal 2, @value.length
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class StringWithCapitalTest < Test::Unit::TestCase
|
59
|
+
def setup
|
60
|
+
@value = String.memorable(:capital => true)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_have_8_characters
|
64
|
+
assert_equal 8, @value.length
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_include_capital
|
68
|
+
assert_match /[A-Z]/, @value
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_should_not_include_digit
|
72
|
+
assert_no_match /[0-9]/, @value
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_should_capitalize_with_length_of_1
|
76
|
+
@value = String.memorable(:capital => true, :length => 1)
|
77
|
+
assert_equal 1, @value.length
|
78
|
+
assert_equal @value.upcase, @value
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_should_be_consistent
|
82
|
+
consistent = (1..1000).all? do
|
83
|
+
value = String.memorable(:capital => true)
|
84
|
+
value =~ /^[a-z]*[A-Z][a-z]*$/
|
85
|
+
end
|
86
|
+
|
87
|
+
assert consistent
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class StringWithDigitTest < Test::Unit::TestCase
|
92
|
+
def setup
|
93
|
+
@value = String.memorable(:digit => true)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_should_have_8_characters
|
97
|
+
assert_equal 8, @value.length
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_not_include_capital
|
101
|
+
assert_no_match /[A-Z]/, @value
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_should_include_digit
|
105
|
+
assert_match /[0-9]/, @value
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_should_always_use_last_character_with_length_of_3
|
109
|
+
@value = String.memorable(:digit => true, :length => 3)
|
110
|
+
assert_equal 3, @value.length
|
111
|
+
assert_match /[0-9]/, @value[-1, 1]
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_should_be_consistent
|
115
|
+
consistent = (1..1000).all? do
|
116
|
+
value = String.memorable(:digit => true)
|
117
|
+
value =~ /^[a-z]+[0-9]{1}[a-z]*$/
|
118
|
+
end
|
119
|
+
|
120
|
+
assert consistent
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class StringWithCapitalAndDigitTest < Test::Unit::TestCase
|
125
|
+
def setup
|
126
|
+
@value = String.memorable(:capital => true, :digit => true)
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_should_have_8_characters
|
130
|
+
assert_equal 8, @value.length
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_include_capital
|
134
|
+
assert_match /[A-Z]/, @value
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_should_include_digit
|
138
|
+
assert_match /[0-9]/, @value
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_should_be_consistent
|
142
|
+
consistent = (1..1000).all? do
|
143
|
+
value = String.memorable(:capital => true, :digit => true)
|
144
|
+
value =~ /^[a-z]*([A-Z][a-z]*[0-9]|[0-9][a-z]*[A-Z])[a-z]*$/
|
145
|
+
end
|
146
|
+
|
147
|
+
assert consistent
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
class StringWithPrintFriendlyTest < Test::Unit::TestCase
|
152
|
+
def setup
|
153
|
+
@value = String.memorable(:print_friendly => true)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_should_have_8_characters
|
157
|
+
assert_equal 8, @value.length
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_not_include_capital
|
161
|
+
assert_no_match /[A-Z]/, @value
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_should_not_include_digit
|
165
|
+
assert_no_match /[0-9]/, @value
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_should_not_include_ambiguous_letters
|
169
|
+
assert_no_match /lio/, @value
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_should_be_consistent
|
173
|
+
consistent = (1..1000).all? do
|
174
|
+
value = String.memorable(:print_friendly => true)
|
175
|
+
value =~ /^[^lio]*$/
|
176
|
+
end
|
177
|
+
|
178
|
+
assert consistent
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class StringWithPrintFriendlyAndCapitalTest < Test::Unit::TestCase
|
183
|
+
def setup
|
184
|
+
@value = String.memorable(:print_friendly => true, :capital => true)
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_should_include_capital
|
188
|
+
assert_match /[A-Z]/, @value
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_should_not_include_digit
|
192
|
+
assert_no_match /[0-9]/, @value
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_should_not_include_ambiguous_letters
|
196
|
+
assert_no_match /lioBDGQSZIO/, @value
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_should_be_consistent
|
200
|
+
consistent = (1..1000).all? do
|
201
|
+
value = String.memorable(:print_friendly => true, :capital => true)
|
202
|
+
value =~ /^[^lioBDGQSZIO]*$/
|
203
|
+
end
|
204
|
+
|
205
|
+
assert consistent
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class StringWithPrintFriendlyAndDigitTest < Test::Unit::TestCase
|
210
|
+
def setup
|
211
|
+
@value = String.memorable(:print_friendly => true, :digit => true)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_should_not_include_capital
|
215
|
+
assert_no_match /[A-Z]/, @value
|
216
|
+
end
|
217
|
+
|
218
|
+
def test_should_include_digit
|
219
|
+
assert_match /[0-9]/, @value
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_should_not_include_ambiguous_letters
|
223
|
+
assert_no_match /lio012568/, @value
|
224
|
+
end
|
225
|
+
|
226
|
+
def test_should_be_consistent
|
227
|
+
consistent = (1..1000).all? do
|
228
|
+
value = String.memorable(:print_friendly => true, :digit => true)
|
229
|
+
value =~ /^[^lio012568]*$/
|
230
|
+
end
|
231
|
+
|
232
|
+
assert consistent
|
233
|
+
end
|
234
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
4
|
+
require File.dirname(__FILE__) + '/../init'
|
5
|
+
|
6
|
+
# Force mocha to be installed
|
7
|
+
begin
|
8
|
+
require 'rubygems'
|
9
|
+
require 'mocha'
|
10
|
+
rescue LoadError
|
11
|
+
$stderr.puts "Mocha is not installed. `gem install mocha` and try again."
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
|
15
|
+
Test::Unit::TestCase.class_eval do
|
16
|
+
def setup_phonemes
|
17
|
+
@vowels = MemorableStrings::Vowel.all.dup
|
18
|
+
@consonants = MemorableStrings::Consonant.all.dup
|
19
|
+
@digits = MemorableStrings::Digit.all.dup
|
20
|
+
|
21
|
+
MemorableStrings::Vowel.all.clear
|
22
|
+
MemorableStrings::Consonant.all.clear
|
23
|
+
MemorableStrings::Digit.all.clear
|
24
|
+
end
|
25
|
+
|
26
|
+
def teardown_phonemes
|
27
|
+
MemorableStrings::Vowel.all.replace(@vowels)
|
28
|
+
MemorableStrings::Consonant.all.replace(@consonants)
|
29
|
+
MemorableStrings::Digit.all.replace(@digits)
|
30
|
+
end
|
31
|
+
end
|
data/test/vowel_test.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class VowelWithPreviousVowelTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
setup_phonemes
|
6
|
+
|
7
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Vowel.new(:b)
|
8
|
+
MemorableStrings::Consonant.all << @br = MemorableStrings::Vowel.new(:br)
|
9
|
+
|
10
|
+
@previous = MemorableStrings::Vowel.new(:a)
|
11
|
+
@vowel = MemorableStrings::Vowel.new(:e)
|
12
|
+
@stack = [@previous, @vowel]
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_generate_consonant_with_one_character
|
16
|
+
MemorableStrings::Consonant.expects(:rand).with(1).returns(0)
|
17
|
+
assert_equal @b, @vowel.next(@stack, 2)
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
teardown_phonemes
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class VowelWithMultipleCharactersTest < Test::Unit::TestCase
|
26
|
+
def setup
|
27
|
+
setup_phonemes
|
28
|
+
|
29
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Vowel.new(:b)
|
30
|
+
MemorableStrings::Consonant.all << @br = MemorableStrings::Vowel.new(:br)
|
31
|
+
|
32
|
+
@previous = MemorableStrings::Consonant.new(:c)
|
33
|
+
@vowel = MemorableStrings::Vowel.new(:ai)
|
34
|
+
@stack = [@previous, @vowel]
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_should_generate_consonant_with_one_character
|
38
|
+
MemorableStrings::Consonant.expects(:rand).with(1).returns(0)
|
39
|
+
assert_equal @b, @vowel.next(@stack, 2)
|
40
|
+
end
|
41
|
+
|
42
|
+
def teardown
|
43
|
+
teardown_phonemes
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class VowelNextTest < Test::Unit::TestCase
|
48
|
+
def setup
|
49
|
+
setup_phonemes
|
50
|
+
|
51
|
+
@previous = MemorableStrings::Consonant.new(:c)
|
52
|
+
@vowel = MemorableStrings::Vowel.new(:a)
|
53
|
+
@stack = [@previous, @vowel]
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_generate_vowel_forty_percent_the_time
|
57
|
+
MemorableStrings::Vowel.all << @e = MemorableStrings::Vowel.new(:e)
|
58
|
+
MemorableStrings::Vowel.all << @ee = MemorableStrings::Vowel.new(:ee)
|
59
|
+
|
60
|
+
(0..3).each do |value|
|
61
|
+
@vowel.expects(:rand).with(10).returns(value)
|
62
|
+
MemorableStrings::Vowel.expects(:rand).with(1).returns(0)
|
63
|
+
|
64
|
+
assert_equal @e, @vowel.next(@stack, 2)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_generate_consonant_sixty_percent_the_time
|
69
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Vowel.new(:b)
|
70
|
+
MemorableStrings::Consonant.all << @br = MemorableStrings::Vowel.new(:br)
|
71
|
+
|
72
|
+
(4..9).each do |value|
|
73
|
+
@vowel.expects(:rand).with(10).returns(value)
|
74
|
+
MemorableStrings::Consonant.expects(:rand).with(1).returns(0)
|
75
|
+
|
76
|
+
assert_equal @b, @vowel.next(@stack, 2)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_should_allow_block_conditional
|
81
|
+
MemorableStrings::Consonant.all << @b = MemorableStrings::Vowel.new(:b)
|
82
|
+
MemorableStrings::Consonant.all << @c = MemorableStrings::Vowel.new(:c)
|
83
|
+
MemorableStrings::Consonant.expects(:rand).with(2).times(2).returns(1, 0)
|
84
|
+
@vowel.expects(:rand).returns(4)
|
85
|
+
|
86
|
+
assert_equal @b, @vowel.next(@stack, 2) {|phoneme| phoneme.value == 'b'}
|
87
|
+
end
|
88
|
+
|
89
|
+
def teardown
|
90
|
+
teardown_phonemes
|
91
|
+
end
|
92
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: memorable_strings
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Pfeifer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-18 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: aaron@pluginaweek.org
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/memorable_strings.rb
|
26
|
+
- lib/memorable_strings
|
27
|
+
- lib/memorable_strings/vowel.rb
|
28
|
+
- lib/memorable_strings/consonant.rb
|
29
|
+
- lib/memorable_strings/extensions
|
30
|
+
- lib/memorable_strings/extensions/string.rb
|
31
|
+
- lib/memorable_strings/digit.rb
|
32
|
+
- lib/memorable_strings/phoneme.rb
|
33
|
+
- test/test_helper.rb
|
34
|
+
- test/consonant_test.rb
|
35
|
+
- test/string_test.rb
|
36
|
+
- test/phoneme_test.rb
|
37
|
+
- test/digit_test.rb
|
38
|
+
- test/vowel_test.rb
|
39
|
+
- CHANGELOG.rdoc
|
40
|
+
- init.rb
|
41
|
+
- LICENSE
|
42
|
+
- Rakefile
|
43
|
+
- README.rdoc
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://www.pluginaweek.org
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
requirements: []
|
64
|
+
|
65
|
+
rubyforge_project: pluginaweek
|
66
|
+
rubygems_version: 1.3.1
|
67
|
+
signing_key:
|
68
|
+
specification_version: 2
|
69
|
+
summary: Generates strings that can be easily remembered
|
70
|
+
test_files:
|
71
|
+
- test/consonant_test.rb
|
72
|
+
- test/string_test.rb
|
73
|
+
- test/phoneme_test.rb
|
74
|
+
- test/digit_test.rb
|
75
|
+
- test/vowel_test.rb
|