username_suggester 0.2.2 → 0.3.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/.gitignore +18 -3
- data/Gemfile +2 -0
- data/README.rdoc +2 -0
- data/Rakefile +5 -28
- data/init.rb +1 -0
- data/lib/username_suggester.rb +2 -6
- data/lib/username_suggester/error.rb +3 -0
- data/lib/username_suggester/suggester.rb +34 -31
- data/lib/username_suggester/suggestions_for.rb +23 -15
- data/lib/username_suggester/version.rb +3 -0
- data/spec/spec_helper.rb +9 -11
- data/spec/username_suggester/suggester_spec.rb +60 -0
- data/spec/username_suggester/suggestions_for_spec.rb +76 -0
- data/username_suggester.gemspec +19 -51
- metadata +117 -68
- data/spec/db/database.yml +0 -10
- data/spec/db/schema.rb +0 -7
- data/spec/suggester_spec.rb +0 -60
- data/spec/suggestions_for_spec.rb +0 -40
data/.gitignore
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
.idea
|
2
|
+
*.gem
|
3
|
+
*.rbc
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.yardoc
|
7
|
+
Gemfile.lock
|
8
|
+
InstalledFiles
|
9
|
+
_yardoc
|
10
|
+
coverage
|
11
|
+
doc/
|
12
|
+
lib/bundler/man
|
13
|
+
pkg
|
14
|
+
rdoc
|
15
|
+
spec/reports
|
16
|
+
test/tmp
|
17
|
+
test/version_tmp
|
18
|
+
tmp
|
data/Gemfile
ADDED
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -1,30 +1,7 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require 'spec/rake/spectask'
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rspec/core/rake_task"
|
5
4
|
|
6
|
-
|
7
|
-
task :default => :spec
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
6
|
|
9
|
-
|
10
|
-
Spec::Rake::SpecTask.new(:spec) do |t|
|
11
|
-
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
12
|
-
t.spec_files = FileList['spec/**/*_spec.rb']
|
13
|
-
end
|
14
|
-
|
15
|
-
desc 'Test the username_suggester plugin.'
|
16
|
-
Rake::TestTask.new(:test) do |t|
|
17
|
-
t.libs << 'lib'
|
18
|
-
t.libs << 'test'
|
19
|
-
t.pattern = 'test/**/*_test.rb'
|
20
|
-
t.verbose = true
|
21
|
-
end
|
22
|
-
|
23
|
-
desc 'Generate documentation for the username_suggester plugin.'
|
24
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
25
|
-
rdoc.rdoc_dir = 'rdoc'
|
26
|
-
rdoc.title = 'UsernameSuggester'
|
27
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
28
|
-
rdoc.rdoc_files.include('README')
|
29
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
30
|
-
end
|
7
|
+
task :default => :spec
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'username_suggester'
|
data/lib/username_suggester.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
|
1
|
+
require "username_suggester/error"
|
2
2
|
require "username_suggester/suggester"
|
3
|
-
|
4
|
-
if defined?(ActiveRecord)
|
5
|
-
require "username_suggester/suggestions_for"
|
6
|
-
ActiveRecord::Base.send :include, UsernameSuggester::UsernameSuggestions
|
7
|
-
end
|
3
|
+
require "username_suggester/suggestions_for"
|
@@ -1,62 +1,65 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
1
|
module UsernameSuggester
|
4
2
|
class Suggester
|
5
|
-
|
6
|
-
attr_reader :last_name
|
7
|
-
|
8
|
-
#
|
3
|
+
|
4
|
+
attr_reader :first_name, :last_name
|
5
|
+
|
6
|
+
# A Suggester class to suggest user_names
|
9
7
|
#
|
10
8
|
# ==== Parameters
|
11
9
|
#
|
12
|
-
# * <tt>:first_name</tt>
|
13
|
-
# * <tt>:last_name</tt>
|
14
|
-
# * <tt>:options</tt>
|
15
|
-
# be returned if involving the Proc with the suggestion returns true
|
10
|
+
# * <tt>:first_name</tt> - Required.
|
11
|
+
# * <tt>:last_name</tt> - Required.
|
12
|
+
# * <tt>:options</tt> - See UsernameSuggester::SuggestionsFor
|
16
13
|
#
|
17
|
-
def initialize(first_name, last_name
|
18
|
-
|
19
|
-
|
20
|
-
@
|
14
|
+
def initialize(first_name, last_name)
|
15
|
+
raise Error, "first_name or last_name has not been specified" if first_name.nil? || last_name.nil?
|
16
|
+
|
17
|
+
@first_name = first_name.downcase.gsub(/[^\w]/, '')
|
18
|
+
@last_name = last_name.downcase.gsub(/[^\w]/, '')
|
21
19
|
end
|
22
20
|
|
23
21
|
# Generates the combinations without the knowledge of what names are available
|
24
22
|
def name_combinations
|
25
23
|
@name_combinations ||= [
|
26
|
-
"#{
|
27
|
-
"#{
|
28
|
-
"#{
|
29
|
-
"#{
|
30
|
-
"#{
|
31
|
-
"#{
|
32
|
-
"#{
|
33
|
-
"#{
|
24
|
+
"#{first_name}",
|
25
|
+
"#{last_name}",
|
26
|
+
"#{first_name[0]}#{last_name}",
|
27
|
+
"#{first_name}#{last_name[0]}",
|
28
|
+
"#{first_name}#{last_name}",
|
29
|
+
"#{last_name[0]}#{first_name}",
|
30
|
+
"#{last_name}#{first_name[0]}",
|
31
|
+
"#{last_name}#{first_name}"
|
34
32
|
].uniq.reject { |s| s.blank? }
|
35
33
|
end
|
36
34
|
|
37
35
|
# Generates suggestions and making sure they are not in unavailable_suggestions
|
38
|
-
def suggest(
|
39
|
-
|
40
|
-
|
36
|
+
def suggest(options)
|
37
|
+
candidates_to_exclude = options[:exclude]
|
38
|
+
validation_block = options[:validate]
|
39
|
+
number_of_suggestions = options[:num_suggestions]
|
40
|
+
|
41
|
+
results = []
|
41
42
|
candidates = name_combinations.clone
|
42
|
-
while results.size <
|
43
|
+
while results.size < number_of_suggestions && !candidates.blank?
|
43
44
|
candidate = candidates.shift
|
44
|
-
if
|
45
|
+
if validation_block.try(:call, candidate)
|
45
46
|
# Don't add the candidate to result
|
46
|
-
elsif
|
47
|
-
candidates << find_extended_candidate(candidate,
|
47
|
+
elsif candidates_to_exclude.include? candidate
|
48
|
+
candidates << find_extended_candidate(candidate, candidates_to_exclude)
|
48
49
|
else
|
49
50
|
results << candidate
|
50
51
|
end
|
51
52
|
end
|
53
|
+
|
52
54
|
results
|
53
55
|
end
|
54
56
|
|
55
57
|
private
|
58
|
+
|
56
59
|
# Generates a candidate with "candidate<number>" which is not included in unavailable_set
|
57
|
-
def find_extended_candidate(candidate,
|
60
|
+
def find_extended_candidate(candidate, candidates_to_exclude)
|
58
61
|
i = 1
|
59
|
-
i+=rand(10) while
|
62
|
+
i+=rand(10) while candidates_to_exclude.include? "#{candidate}#{i}"
|
60
63
|
"#{candidate}#{i}"
|
61
64
|
end
|
62
65
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module UsernameSuggester
|
2
|
-
module
|
2
|
+
module SuggestionsFor
|
3
3
|
def self.included(base)
|
4
4
|
base.send :extend, ClassMethods
|
5
5
|
end
|
@@ -19,23 +19,31 @@ module UsernameSuggester
|
|
19
19
|
# <tt>:last_name_attribute</tt>:: The attribute which stores the last name. Default is <tt>:last_name</tt>
|
20
20
|
# <tt>:num_suggestions</tt>:: Maximum suggestions generated. Default is <tt>10</tt>
|
21
21
|
# <tt>:validate</tt>: An Proc object which takes in an username and return true if this is an validate username
|
22
|
-
# <tt>:
|
22
|
+
# <tt>:exclude</tt>: An array of strings that should not be suggested
|
23
23
|
#
|
24
|
-
def suggestions_for(attribute = :username,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
def suggestions_for(attribute = :username, option_hash = {})
|
25
|
+
options = {
|
26
|
+
:first_name_attribute => :first_name,
|
27
|
+
:last_name_attribute => :last_name,
|
28
|
+
:num_suggestions => 5,
|
29
|
+
:exclude => []
|
30
|
+
}.merge(option_hash)
|
29
31
|
|
30
|
-
|
31
|
-
suggester = Suggester.new(send(first_name_attribute), send(last_name_attribute)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
define_method "#{attribute}_suggestions" do
|
33
|
+
suggester = Suggester.new(send(options[:first_name_attribute]), send(options[:last_name_attribute]))
|
34
|
+
suggestions_to_search = suggester.name_combinations.map { |s| "#{s}%" }
|
35
|
+
|
36
|
+
t = self.class.arel_table
|
37
|
+
unavailable_choices = self.class.find_by_sql(t.project(t[attribute])
|
38
|
+
.where(t[attribute].matches_any(suggestions_to_search).and(t[:id].not_eq(self.id))).to_sql)
|
39
|
+
.map(&attribute).map(&:downcase).uniq
|
40
|
+
|
41
|
+
options[:exclude] += unavailable_choices
|
42
|
+
suggester.suggest(options)
|
37
43
|
end
|
38
44
|
end
|
39
45
|
end
|
40
46
|
end
|
41
|
-
end
|
47
|
+
end
|
48
|
+
|
49
|
+
ActiveRecord::Base.send :include, UsernameSuggester::SuggestionsFor
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
1
|
+
require 'active_record'
|
2
|
+
require 'with_model'
|
3
|
+
|
4
|
+
# At last require our lib
|
5
|
+
require 'username_suggester'
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.extend WithModel
|
9
|
+
end
|
10
10
|
|
11
|
-
|
12
|
-
ActiveRecord::Base.establish_connection(databases[ENV["DB"] || "mysql"])
|
13
|
-
load(File.join(plugin_spec_dir, "db", "schema.rb"))
|
11
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe UsernameSuggester::Suggester do
|
4
|
+
describe "name combinations" do
|
5
|
+
it "returns default combinations of first name and last name" do
|
6
|
+
UsernameSuggester::Suggester.new("Jerry", "Luk").name_combinations
|
7
|
+
.should eq(%w{jerry luk jluk jerryl jerryluk ljerry lukj lukjerry})
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns first name and first name initial if last name is blank" do
|
11
|
+
UsernameSuggester::Suggester.new("Jerry", "").name_combinations.should eq(%w{jerry j})
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns last name and last name initial if first name is blank" do
|
15
|
+
UsernameSuggester::Suggester.new("", "Luk").name_combinations.should eq(%w{luk l})
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns empty array for blank first name and last name" do
|
19
|
+
UsernameSuggester::Suggester.new("", "").name_combinations.should eq([])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should not contain space even there is a space in names" do
|
23
|
+
UsernameSuggester::Suggester.new("Ting Ting", "").name_combinations.should eq(%w{tingting t})
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "name suggestions options testing" do
|
29
|
+
before(:each) do
|
30
|
+
@suggester = UsernameSuggester::Suggester.new("Jerry", "Luk")
|
31
|
+
@options = { :exclude => [], :num_suggestions => 10 }
|
32
|
+
end
|
33
|
+
|
34
|
+
it "return all available suggestions if no exclusions passed" do
|
35
|
+
@suggester.suggest(@options).should eq(%w{jerry luk jluk jerryl jerryluk ljerry lukj lukjerry})
|
36
|
+
end
|
37
|
+
|
38
|
+
it "return only first 3 suggestions" do
|
39
|
+
@options[:num_suggestions] = 3
|
40
|
+
@suggester.suggest(@options).should eq(%w{jerry luk jluk})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "return suggestions but exclude the ones passed" do
|
44
|
+
@options[:exclude] = ["jerry", "lukjerry"]
|
45
|
+
@suggester.suggest(@options).should_not include("jerry", "lukjerry")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "return alternative when excluded" do
|
49
|
+
@options[:exclude] = ["jerry"]
|
50
|
+
@suggester.suggest(@options).should include("jerry1")
|
51
|
+
end
|
52
|
+
|
53
|
+
it "filter out candidates using a proc block aka validation" do
|
54
|
+
# Remove all suggestions starting with j
|
55
|
+
@options[:validate] = proc { |s| s =~ /^j/ }
|
56
|
+
@suggester.suggest(@options).should eq(%w{luk ljerry lukj lukjerry})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe UsernameSuggester::SuggestionsFor do
|
4
|
+
|
5
|
+
describe "default options given" do
|
6
|
+
|
7
|
+
with_model :User do
|
8
|
+
# User table migration
|
9
|
+
table do |t|
|
10
|
+
t.string :first_name, :last_name, :username
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
# Lets test suggestions_for without any options
|
15
|
+
# By default there's nothing to exclude and number of suggestions equals 5
|
16
|
+
model do
|
17
|
+
suggestions_for :username
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
@user = User.create(:first_name => "Jerry", :last_name => "Luk")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to suggest usernames" do
|
26
|
+
@user.username_suggestions.should eq(%w{jerry luk jluk jerryl jerryluk})
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should suggest usernames that are not taken" do
|
30
|
+
# Ooops some user stolen our "jerry" username, so we'll not showing it in suggestions array
|
31
|
+
another_user = User.create(:first_name => "Robo", :last_name => "Cop", :username => "jerry")
|
32
|
+
@user.username_suggestions.should_not include("jerry")
|
33
|
+
|
34
|
+
# But is should include some alternative
|
35
|
+
@user.username_suggestions.should_not include("jerry1")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "complex options given" do
|
41
|
+
|
42
|
+
with_model :User do
|
43
|
+
# User table migration
|
44
|
+
table do |t|
|
45
|
+
t.string :first, :last, :login_name
|
46
|
+
t.timestamps
|
47
|
+
end
|
48
|
+
|
49
|
+
model do
|
50
|
+
suggestions_for :login_name, :first_name_attribute => :first,
|
51
|
+
:last_name_attribute => :last,
|
52
|
+
:num_suggestions => 3,
|
53
|
+
:exclude => ["reserved"],
|
54
|
+
:validate => proc { |s| s =~ /admin/ }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
before(:each) do
|
59
|
+
@user = User.create(:first => "Reserved", :last => "Luk Admin")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should exclude 'reserved' from the list of suggestions" do
|
63
|
+
@user.login_name_suggestions.should_not include("reserved")
|
64
|
+
@user.login_name_suggestions.size.should eq(3)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should suggest usernames that are taken by me" do
|
68
|
+
# Even if I have already this username it should suggest me the same cuz it's mine
|
69
|
+
@user.login_name = "reservedl"
|
70
|
+
@user.save
|
71
|
+
@user.login_name_suggestions.should include("reservedl")
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/username_suggester.gemspec
CHANGED
@@ -1,55 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
s.version = "0.2.2"
|
4
|
-
|
5
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
-
s.authors = ["jerryluk"]
|
7
|
-
s.date = %q{2010-06-30}
|
8
|
-
s.description = %q{Generates username suggestions for users}
|
9
|
-
s.email = %q{jerry@presdo.com}
|
10
|
-
s.extra_rdoc_files = [
|
11
|
-
"MIT-LICENSE",
|
12
|
-
"README.rdoc"
|
13
|
-
]
|
14
|
-
s.files = [
|
15
|
-
".gitignore",
|
16
|
-
"MIT-LICENSE",
|
17
|
-
"README.rdoc",
|
18
|
-
"Rakefile",
|
19
|
-
"username_suggester.gemspec",
|
20
|
-
"lib/username_suggester.rb",
|
21
|
-
"lib/username_suggester/suggester.rb",
|
22
|
-
"lib/username_suggester/suggestions_for.rb",
|
23
|
-
"spec/suggestions_for_spec.rb",
|
24
|
-
"spec/suggester_spec.rb",
|
25
|
-
"spec/spec_helper.rb",
|
26
|
-
"spec/db/database.yml",
|
27
|
-
"spec/db/schema.rb"
|
28
|
-
]
|
29
|
-
s.homepage = %q{http://github.com/jerryluk/username_suggester}
|
30
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
-
s.require_paths = ["lib"]
|
32
|
-
s.rubygems_version = %q{1.3.6}
|
33
|
-
s.summary = %q{Generates username suggestions for users}
|
34
|
-
s.test_files = [
|
35
|
-
"spec/suggestions_for_spec.rb",
|
36
|
-
"spec/suggester_spec.rb",
|
37
|
-
"spec/spec_helper.rb",
|
38
|
-
"spec/db/database.yml",
|
39
|
-
"spec/db/schema.rb"
|
40
|
-
]
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/username_suggester/version', __FILE__)
|
41
3
|
|
42
|
-
|
43
|
-
|
44
|
-
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "username_suggester"
|
6
|
+
s.version = UsernameSuggester::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.summary = "Generates username suggestions for users"
|
9
|
+
s.required_rubygems_version = ">= 1.3.6"
|
10
|
+
s.authors = ["jerryluk", "fillman"]
|
11
|
+
s.email = ["jerry@presdo.com", "fila.luka@gmail.com"]
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.require_path = ["lib"]
|
15
|
+
s.homepage = "https://github.com/jerryluk/username_suggester"
|
45
16
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
else
|
52
|
-
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
53
|
-
end
|
17
|
+
s.add_development_dependency 'with_model', '~> 0.3'
|
18
|
+
s.add_development_dependency 'rspec', '~> 2.11.0'
|
19
|
+
s.add_development_dependency 'activerecord', '~> 3.1'
|
20
|
+
s.add_development_dependency 'rake', '~> 0.9'
|
21
|
+
s.add_development_dependency 'sqlite3', '~> 1.3.6'
|
54
22
|
end
|
55
23
|
|
metadata
CHANGED
@@ -1,99 +1,148 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: username_suggester
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 2
|
10
|
-
version: 0.2.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- jerryluk
|
9
|
+
- fillman
|
14
10
|
autorequire:
|
15
11
|
bindir: bin
|
16
12
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
13
|
+
date: 2012-10-08 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: with_model
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.3'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0.3'
|
31
|
+
- !ruby/object:Gem::Dependency
|
22
32
|
name: rspec
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 2.11.0
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.11.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: activerecord
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
type: :development
|
23
56
|
prerelease: false
|
24
|
-
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.1'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rake
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
25
66
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 2
|
33
|
-
- 9
|
34
|
-
version: 1.2.9
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0.9'
|
35
71
|
type: :development
|
36
|
-
|
37
|
-
|
38
|
-
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0.9'
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: sqlite3
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ~>
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.3.6
|
87
|
+
type: :development
|
88
|
+
prerelease: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.3.6
|
95
|
+
description:
|
96
|
+
email:
|
97
|
+
- jerry@presdo.com
|
98
|
+
- fila.luka@gmail.com
|
39
99
|
executables: []
|
40
|
-
|
41
100
|
extensions: []
|
42
|
-
|
43
|
-
|
44
|
-
- MIT-LICENSE
|
45
|
-
- README.rdoc
|
46
|
-
files:
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
47
103
|
- .gitignore
|
104
|
+
- Gemfile
|
48
105
|
- MIT-LICENSE
|
49
106
|
- README.rdoc
|
50
107
|
- Rakefile
|
51
|
-
-
|
108
|
+
- init.rb
|
52
109
|
- lib/username_suggester.rb
|
110
|
+
- lib/username_suggester/error.rb
|
53
111
|
- lib/username_suggester/suggester.rb
|
54
112
|
- lib/username_suggester/suggestions_for.rb
|
55
|
-
-
|
56
|
-
- spec/suggester_spec.rb
|
113
|
+
- lib/username_suggester/version.rb
|
57
114
|
- spec/spec_helper.rb
|
58
|
-
- spec/
|
59
|
-
- spec/
|
60
|
-
|
61
|
-
homepage:
|
115
|
+
- spec/username_suggester/suggester_spec.rb
|
116
|
+
- spec/username_suggester/suggestions_for_spec.rb
|
117
|
+
- username_suggester.gemspec
|
118
|
+
homepage: https://github.com/jerryluk/username_suggester
|
62
119
|
licenses: []
|
63
|
-
|
64
120
|
post_install_message:
|
65
|
-
rdoc_options:
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- - lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
125
|
none: false
|
71
|
-
requirements:
|
72
|
-
- -
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
|
75
|
-
segments:
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
segments:
|
76
131
|
- 0
|
77
|
-
|
78
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
hash: -4164584086967831757
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
134
|
none: false
|
80
|
-
requirements:
|
81
|
-
- -
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
|
84
|
-
segments:
|
85
|
-
- 0
|
86
|
-
version: "0"
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.3.6
|
87
139
|
requirements: []
|
88
|
-
|
89
140
|
rubyforge_project:
|
90
|
-
rubygems_version: 1.
|
141
|
+
rubygems_version: 1.8.24
|
91
142
|
signing_key:
|
92
143
|
specification_version: 3
|
93
144
|
summary: Generates username suggestions for users
|
94
|
-
test_files:
|
95
|
-
- spec/suggestions_for_spec.rb
|
96
|
-
- spec/suggester_spec.rb
|
145
|
+
test_files:
|
97
146
|
- spec/spec_helper.rb
|
98
|
-
- spec/
|
99
|
-
- spec/
|
147
|
+
- spec/username_suggester/suggester_spec.rb
|
148
|
+
- spec/username_suggester/suggestions_for_spec.rb
|
data/spec/db/database.yml
DELETED
data/spec/db/schema.rb
DELETED
data/spec/suggester_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
|
3
|
-
describe UsernameSuggester::Suggester do
|
4
|
-
describe "name combinations" do
|
5
|
-
it "returns combinations of first name and last name" do
|
6
|
-
UsernameSuggester::Suggester.new("Jerry", "Luk").name_combinations.should == [
|
7
|
-
"jerry",
|
8
|
-
"luk",
|
9
|
-
"jluk",
|
10
|
-
"jerryl",
|
11
|
-
"jerryluk",
|
12
|
-
"ljerry",
|
13
|
-
"lukj",
|
14
|
-
"lukjerry"
|
15
|
-
]
|
16
|
-
end
|
17
|
-
|
18
|
-
it "returns first name and first name initial if last name is blank" do
|
19
|
-
UsernameSuggester::Suggester.new("Jerry", "").name_combinations.should == [
|
20
|
-
"jerry",
|
21
|
-
"j"
|
22
|
-
]
|
23
|
-
end
|
24
|
-
|
25
|
-
it "returns last name and last name initial if first name is blank" do
|
26
|
-
UsernameSuggester::Suggester.new("", "Luk").name_combinations.should == [
|
27
|
-
"luk",
|
28
|
-
"l"
|
29
|
-
]
|
30
|
-
end
|
31
|
-
|
32
|
-
it "returns empty array for blank first name and last name" do
|
33
|
-
UsernameSuggester::Suggester.new("", "").name_combinations.should == []
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe "name suggestions" do
|
38
|
-
before(:each) do
|
39
|
-
@suggester = UsernameSuggester::Suggester.new("Jerry", "Luk")
|
40
|
-
end
|
41
|
-
|
42
|
-
it "returns suggestions for names that are not in the unavailable suggestions" do
|
43
|
-
@suggester.suggest(5, []).should == ["jerry", "luk", "jluk", "jerryl", "jerryluk"]
|
44
|
-
end
|
45
|
-
|
46
|
-
it "returns extended suggestions for names that are in the unavailable suggestions" do
|
47
|
-
UsernameSuggester::Suggester.send(:define_method, :rand) { 1 }
|
48
|
-
@suggester.suggest(10, ["jerry"]).should include "jerry1"
|
49
|
-
@suggester.suggest(10, ["jerry", "jerry1"]).should include "jerry2"
|
50
|
-
@suggester.suggest(10, ["jerry", "jerry1031"]).should include "jerry1"
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should only returns suggestions passing the validate proc" do
|
54
|
-
suggestions = UsernameSuggester::Suggester.new("Jerry", "Luk",
|
55
|
-
:validate => Proc.new { |s| s.length <= 5 }).suggest(10, [])
|
56
|
-
suggestions.should include "jerry"
|
57
|
-
suggestions.should_not include "jerryl"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
|
3
|
-
class User < ActiveRecord::Base
|
4
|
-
attr_accessible :first_name, :last_name, :username
|
5
|
-
suggestions_for :username, :exclusion => ['luk']
|
6
|
-
end
|
7
|
-
|
8
|
-
describe UsernameSuggester::UsernameSuggestions do
|
9
|
-
before(:each) do
|
10
|
-
@user = User.new(:first_name => "Jerry", :last_name => "Luk")
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should able to suggest usernames" do
|
14
|
-
suggestions = @user.username_suggestions
|
15
|
-
suggestions.should_not be_blank
|
16
|
-
suggestions.should include "jerry"
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should able to suggest usernames that are not taken" do
|
20
|
-
UsernameSuggester::Suggester.send(:define_method, :rand) { 1 }
|
21
|
-
|
22
|
-
User.create!(:username => "jerry")
|
23
|
-
1.upto(10) do |i|
|
24
|
-
User.create!(:username => "jerry#{i}")
|
25
|
-
end
|
26
|
-
suggestions = @user.username_suggestions
|
27
|
-
suggestions.should_not be_blank
|
28
|
-
suggestions.should_not include "jerry"
|
29
|
-
suggestions.should include "jerry11"
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should not suggest usernames in the exclusion list" do
|
33
|
-
UsernameSuggester::Suggester.send(:define_method, :rand) { 1 }
|
34
|
-
|
35
|
-
suggestions = @user.username_suggestions
|
36
|
-
suggestions.should_not be_blank
|
37
|
-
suggestions.should_not include "luk"
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|