usernamegen 0.1.2 → 0.2.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.
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