username_suggester 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|