usernamegen 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6470180a69432a0dbe28897cffeb5e623c5d9709
4
- data.tar.gz: 3885e1ed4209b76453d412fd8e9b16819126b3c5
3
+ metadata.gz: 9f0ca1cfb4a4ddf8b04cd0e9db2a5822ac8044e7
4
+ data.tar.gz: f86c87036862f9562c317beea6963058a1315320
5
5
  SHA512:
6
- metadata.gz: 4320a755335eeb1ce9872eab670a0291c88e054248583eb3e1406d89de3c708922e1d1a814416e6121606a2a75a190f40959b289e974707033512ab5ae642367
7
- data.tar.gz: b92cce25e590fcd6306b6151949cc003c9cc30fdd324d8896c77aab0e3ff00e3d5070277c390247eac70d31b3365e22b924d2a653d0a6371613dad4d83704bb4
6
+ metadata.gz: 1d84ace35ce78f6b9a7c626406701c4f4f127c17d5f7a3f55a0b975178e4aa963c44c6823741aa29675920d3c417fac1a0c70bde638d7631811848c7872a617c
7
+ data.tar.gz: cfc47f6d92bba727d15718772fbef456172fc8950072bc1c105bdc6b9c6e4cfcc6d7794cb56d4c86465d1e1f820a9ff5cac74c6d5ee68c5b53a6d70efe2043d2
data/README.md CHANGED
@@ -18,6 +18,7 @@ This gem uses two lists (descriptive words and nouns) and multiplies them with e
18
18
  * Chemical Rabbit
19
19
  * [surprise me](https://de.gamesplanet.com/namegen)
20
20
 
21
+
21
22
  ## Installation
22
23
 
23
24
  Requires Ruby >= 1.9.3
@@ -30,21 +31,88 @@ Or list in your Gemfile
30
31
 
31
32
  gem 'usernamegen'
32
33
 
34
+
33
35
  ## Usage
34
36
 
35
- You can use the generator class like so:
37
+ You can use the generator class like so (also see Caching/Benchmark):
38
+
39
+ ```ruby
40
+ # Assembles whole list each time (yielding more than 1 million strings, cache them!)
41
+ Usernamegen.all
42
+
43
+ # Samples one item from both lists and assembles them (fast)
44
+ Usernamegen.one
45
+
46
+ # Uses multiple `#one` calls to give you an array of names without having to take a subset of `#all`.
47
+ # You may get duplicate names! This is just a shorthand as simple as `AMOUNT.times.map{ one }`.
48
+ Usernamegen.some(10)
49
+
50
+ # Assembles a list for a given thing (huge result set)
51
+ Usernamegen.all_for_thing("thing")
52
+
53
+ # Assembles a list for a given description (huge result set)
54
+ Usernamegen.all_for_desc("description")
55
+ ```
56
+
57
+ Initiating the class will instantly load the two text files into memory (as array). You can also use the instance approach if you have multiple calls to the generator.
58
+
59
+ ```ruby
60
+ generator = Usernamegen.new(opts = {}, &formatter)
61
+ generator.one
62
+ generator.all_for_thing
63
+ ```
64
+
65
+ ## Custom format
66
+
67
+ You can return usernames in your custom format at all methods. Just pass a block, e.g.:
68
+
69
+ ```ruby
70
+ Usernamegen.one { |combination| combination.join("-").downcase }
71
+ => "able-action"
72
+ ```
36
73
 
37
- # load files and assembles list each time (yielding more than 1 million strings, cache them!)
38
- Usernamegen.all
74
+ If you use the instance approach you may also want to redefine the default format.
39
75
 
40
- # same as #all but returns random entry
41
- Usernamegen.one
76
+ ```ruby
77
+ generator = Usernamegen.new format: ->(combination){ combination.join("-").downcase }
42
78
 
79
+ # or sugar version
80
+ generator = Usernamegen.new { |combination| combination.join("-").downcase }
43
81
 
44
- You can find an example ActiveRecord model + rake import tasks in the following gist.
82
+ generator.one
83
+ => "malicious-expert"
84
+ ```
45
85
 
86
+
87
+ ## Options
88
+
89
+ The generator class has a few options but except for the format option there is little reason for you to change them.
90
+
91
+ ```ruby
92
+ Usernamegen.new({
93
+ # The default format (note that passing a block to #new will overwrite the hash option)
94
+ format: ->(combination){ combination.join(" ").titleize },
95
+
96
+ # This option only exists for testing
97
+ rng: ::SecureRandom.urlsafe_base64(128),
98
+
99
+ # You could point to different word lists here
100
+ descriptions: "#{ROOT}/lib/usernamegen/descriptions.txt",
101
+ things: "#{ROOT}/lib/usernamegen/things.txt",
102
+ })
103
+ ```
104
+
105
+
106
+ ## Caching / Benchmark
107
+
108
+ While the `#one` and `#some` methods are quite fast it's still advised to import the combinations to your database in a batch fashion opposed to generate single names on the fly.
109
+
110
+ We suggest a separate _Codename_ model and assign a free name to a user when he needs one (usually upon registration or first post). You can find an example ActiveRecord model + rake import tasks in the following gist.
111
+
112
+ * [» Benchmarks](https://gist.github.com/2called-chaos/a0ea619fdc7ef245719d)
46
113
  * [» ActiveRecord model example and rake import task](https://gist.github.com/2called-chaos/46705324d913e4f9cc6b)
47
114
 
115
+
48
116
  ## Testing
49
117
 
50
118
  Just `bundle` and invoke `rake`.
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require "bundler/gem_tasks"
2
-
3
2
  require 'rake/testtask'
4
3
 
5
4
  Rake::TestTask.new do |t|
@@ -7,3 +6,196 @@ Rake::TestTask.new do |t|
7
6
  end
8
7
 
9
8
  task :default => [:test]
9
+
10
+ desc "Gives you 10 random names (5 with default/5 with custom format)"
11
+ task :example do
12
+ require 'usernamegen'
13
+ instance = Usernamegen.new
14
+ 5.times { puts instance.one }
15
+ instance = Usernamegen.new {|a| a.join("-").downcase }
16
+ puts instance.some(5)
17
+ end
18
+
19
+ desc "Gives you ALL names"
20
+ task :all_names do
21
+ require 'usernamegen'
22
+ Usernamegen.new.all.each{|n| puts n }
23
+ end
24
+
25
+ desc "Run performance benchmarks with benchmark-ips tests"
26
+ task :benchmark do
27
+ require 'usernamegen'
28
+ require 'benchmark'
29
+ require 'benchmark/ips'
30
+
31
+ # initial load
32
+ instance = nil
33
+ Benchmark.benchmark do |x|
34
+ x.report("initial load") { instance = Usernamegen.new }
35
+ end
36
+
37
+ # misc
38
+ Benchmark.ips do |x|
39
+ x.time = 5
40
+ x.warmup = 2
41
+
42
+ # loading files (cached since we loaded already once)
43
+ x.report("::new") do |times|
44
+ i = 0
45
+ while i < times
46
+ Usernamegen.new
47
+ i += 1
48
+ end
49
+ end
50
+ end ; puts
51
+
52
+ # one
53
+ Benchmark.ips do |x|
54
+ x.time = 5
55
+ x.warmup = 2
56
+
57
+ x.report("::one") do |times|
58
+ i = 0
59
+ while i < times
60
+ Usernamegen.one
61
+ i += 1
62
+ end
63
+ end
64
+
65
+ x.report("#one") do |times|
66
+ i = 0
67
+ while i < times
68
+ instance.one
69
+ i += 1
70
+ end
71
+ end
72
+
73
+ x.compare!
74
+ end ; puts
75
+
76
+ # instance compare
77
+ Benchmark.ips do |x|
78
+ x.time = 5
79
+ x.warmup = 2
80
+
81
+ x.report("#one") do |times|
82
+ i = 0
83
+ while i < times
84
+ instance.one
85
+ i += 1
86
+ end
87
+ end
88
+
89
+ x.report("#some(1)") do |times|
90
+ i = 0
91
+ while i < times
92
+ instance.some(1)
93
+ i += 1
94
+ end
95
+ end
96
+
97
+ x.report("#some(10)") do |times|
98
+ i = 0
99
+ while i < times
100
+ instance.some(10)
101
+ i += 1
102
+ end
103
+ end
104
+
105
+ x.report("#all") do |times|
106
+ i = 0
107
+ while i < times
108
+ instance.all
109
+ i += 1
110
+ end
111
+ end
112
+
113
+ x.report("#all_for_thing") do |times|
114
+ i = 0
115
+ while i < times
116
+ instance.all_for_thing("foo")
117
+ i += 1
118
+ end
119
+ end
120
+
121
+ x.report("#all_for_desc") do |times|
122
+ i = 0
123
+ while i < times
124
+ instance.all_for_desc("bar")
125
+ i += 1
126
+ end
127
+ end
128
+
129
+ x.compare!
130
+ end ; puts
131
+ end
132
+
133
+
134
+ desc "test benchmark (for while developing)"
135
+ task :testbench do
136
+ require 'usernamegen'
137
+ require 'benchmark'
138
+ require 'benchmark/ips'
139
+
140
+ # initial load
141
+ Benchmark.ips do |x|
142
+ x.time = 5
143
+ x.warmup = 2
144
+ instance = Usernamegen.new
145
+
146
+ x.report("#one") do |times|
147
+ i = 0
148
+ while i < times
149
+ instance.one
150
+ i += 1
151
+ end
152
+ end
153
+
154
+ x.report("#some(1)") do |times|
155
+ i = 0
156
+ while i < times
157
+ instance.some(1)
158
+ i += 1
159
+ end
160
+ end
161
+
162
+ x.report("#some(10)") do |times|
163
+ i = 0
164
+ while i < times
165
+ instance.some(10)
166
+ i += 1
167
+ end
168
+ end
169
+
170
+ x.compare!
171
+ end ; puts
172
+ end
173
+
174
+
175
+ desc "test benchmark (for while developing)"
176
+ task :testbench do
177
+ require 'usernamegen'
178
+ require 'benchmark'
179
+ require 'benchmark/ips'
180
+
181
+ # initial load
182
+ instance = nil
183
+ Benchmark.benchmark do |x|
184
+ x.report("initial load") { instance = Usernamegen.new }
185
+ end
186
+
187
+ Benchmark.ips do |x|
188
+ x.time = 5
189
+ x.warmup = 2
190
+
191
+ x.report("???") do |times|
192
+ i = 0
193
+ while i < times
194
+ ###
195
+ i += 1
196
+ end
197
+ end
198
+
199
+ x.compare!
200
+ end
201
+ end
@@ -1,3 +1,3 @@
1
1
  class Usernamegen
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/usernamegen.rb CHANGED
@@ -6,27 +6,32 @@ require "active_support/core_ext"
6
6
  class Usernamegen
7
7
  ROOT = File.expand_path("../..", __FILE__)
8
8
 
9
- def self.one opts = {}
10
- new(opts).one
9
+ def self.one(opts = {}, &block)
10
+ new(opts).one(&block)
11
11
  end
12
12
 
13
- def self.all opts = {}
14
- new(opts).all
13
+ def self.some(amount, opts = {}, &block)
14
+ new(opts).some(amount, &block)
15
15
  end
16
16
 
17
- def self.all_for_thing thing, opts = {}
18
- new(opts).all_for_thing(thing)
17
+ def self.all(opts = {}, &block)
18
+ new(opts).all(&block)
19
19
  end
20
20
 
21
- def self.all_for_desc desc, opts = {}
22
- new(opts).all_for_desc(desc)
21
+ def self.all_for_thing(thing, opts = {}, &block)
22
+ new(opts).all_for_thing(thing, &block)
23
23
  end
24
24
 
25
- def initialize opts = {}
25
+ def self.all_for_desc(desc, opts = {}, &block)
26
+ new(opts).all_for_desc(desc, &block)
27
+ end
28
+
29
+ def initialize opts = {}, &block
26
30
  @opts = opts.reverse_merge({
27
31
  descriptions: "#{ROOT}/lib/usernamegen/descriptions.txt",
28
32
  things: "#{ROOT}/lib/usernamegen/things.txt",
29
33
  rng: ::SecureRandom.urlsafe_base64(128),
34
+ format: block || ->(combination){ combination.join(" ").titleize },
30
35
  })
31
36
  @descriptions = load_file @opts[:descriptions]
32
37
  @things = load_file @opts[:things]
@@ -36,19 +41,24 @@ class Usernamegen
36
41
  File.read(file).split("\n").map(&:strip).reject(&:blank?)
37
42
  end
38
43
 
39
- def one
40
- [@descriptions.sample(1, random: @opts[:rng]), @things.sample(1, random: @opts[:rng])].join(" ").titleize
44
+ def one &block
45
+ combination = [@descriptions.sample(1, random: @opts[:rng]), @things.sample(1, random: @opts[:rng])]
46
+ (block || @opts[:format]).call(combination)
47
+ end
48
+
49
+ def some amount, &block
50
+ amount.times.map{ one(&block) }
41
51
  end
42
52
 
43
- def all
44
- @descriptions.product(@things).map{|combination| combination.join(" ").titleize }
53
+ def all &block
54
+ @descriptions.product(@things).map(&(block || @opts[:format]))
45
55
  end
46
56
 
47
- def all_for_thing thing
48
- @descriptions.product([thing]).map{|combination| combination.join(" ").titleize }
57
+ def all_for_thing thing, &block
58
+ @descriptions.product([thing]).map(&(block || @opts[:format]))
49
59
  end
50
60
 
51
- def all_for_desc desc
52
- [desc].product(@things).map{|combination| combination.join(" ").titleize }
61
+ def all_for_desc desc, &block
62
+ [desc].product(@things).map(&(block || @opts[:format]))
53
63
  end
54
64
  end
@@ -10,6 +10,15 @@ class TestUsernamegen < Minitest::Test
10
10
  end
11
11
  end
12
12
 
13
+ def test_default_format
14
+ assert_match /^([A-Z][a-z]*((\s)))+[A-Z][a-z]*$/, Usernamegen.one
15
+ end
16
+
17
+ def test_custom_format
18
+ username = Usernamegen.one { |username| username.join("-").downcase }
19
+ assert_match /^([a-z]*((-)))+[a-z]*$/, username
20
+ end
21
+
13
22
  def test_amount_of_names
14
23
  # don't forget to update README as well!
15
24
  assert_equal Usernamegen.all.count, 1_367_631
data/usernamegen.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.5"
24
24
  spec.add_development_dependency "minitest"
25
25
  spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "benchmark-ips"
26
27
  end
metadata CHANGED
@@ -1,69 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: usernamegen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Pachnit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-21 00:00:00.000000000 Z
11
+ date: 2015-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 2.3.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.3.8
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.5'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: benchmark-ips
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  description: This gem uses two lists (descriptive words and nouns) and multiplies
@@ -75,8 +89,8 @@ executables: []
75
89
  extensions: []
76
90
  extra_rdoc_files: []
77
91
  files:
78
- - .gitignore
79
- - .travis.yml
92
+ - ".gitignore"
93
+ - ".travis.yml"
80
94
  - Gemfile
81
95
  - LICENSE.txt
82
96
  - README.md
@@ -97,17 +111,17 @@ require_paths:
97
111
  - lib
98
112
  required_ruby_version: !ruby/object:Gem::Requirement
99
113
  requirements:
100
- - - '>='
114
+ - - ">="
101
115
  - !ruby/object:Gem::Version
102
116
  version: '0'
103
117
  required_rubygems_version: !ruby/object:Gem::Requirement
104
118
  requirements:
105
- - - '>='
119
+ - - ">="
106
120
  - !ruby/object:Gem::Version
107
121
  version: '0'
108
122
  requirements: []
109
123
  rubyforge_project:
110
- rubygems_version: 2.0.14
124
+ rubygems_version: 2.2.2
111
125
  signing_key:
112
126
  specification_version: 4
113
127
  summary: Usernamegen - a not so serious name generator