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 +4 -4
- data/README.md +74 -6
- data/Rakefile +193 -1
- data/lib/usernamegen/version.rb +1 -1
- data/lib/usernamegen.rb +27 -17
- data/test/usernamegen_test.rb +9 -0
- data/usernamegen.gemspec +1 -0
- metadata +29 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f0ca1cfb4a4ddf8b04cd0e9db2a5822ac8044e7
|
4
|
+
data.tar.gz: f86c87036862f9562c317beea6963058a1315320
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
38
|
-
Usernamegen.all
|
74
|
+
If you use the instance approach you may also want to redefine the default format.
|
39
75
|
|
40
|
-
|
41
|
-
|
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
|
-
|
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
|
data/lib/usernamegen/version.rb
CHANGED
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
|
10
|
-
new(opts).one
|
9
|
+
def self.one(opts = {}, &block)
|
10
|
+
new(opts).one(&block)
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.
|
14
|
-
new(opts).
|
13
|
+
def self.some(amount, opts = {}, &block)
|
14
|
+
new(opts).some(amount, &block)
|
15
15
|
end
|
16
16
|
|
17
|
-
def self.
|
18
|
-
new(opts).
|
17
|
+
def self.all(opts = {}, &block)
|
18
|
+
new(opts).all(&block)
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.
|
22
|
-
new(opts).
|
21
|
+
def self.all_for_thing(thing, opts = {}, &block)
|
22
|
+
new(opts).all_for_thing(thing, &block)
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
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])]
|
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
|
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
|
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
|
61
|
+
def all_for_desc desc, &block
|
62
|
+
[desc].product(@things).map(&(block || @opts[:format]))
|
53
63
|
end
|
54
64
|
end
|
data/test/usernamegen_test.rb
CHANGED
@@ -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
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.
|
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:
|
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.
|
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
|