gimei 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gimei/address.rb CHANGED
@@ -19,6 +19,10 @@ class Gimei::Address
19
19
  "#{prefecture.katakana}#{city.katakana}#{town.katakana}"
20
20
  end
21
21
 
22
+ def romaji
23
+ "#{prefecture.romaji} #{city.romaji} #{town.romaji}"
24
+ end
25
+
22
26
  alias_method :to_s, :kanji
23
27
 
24
28
  class Prefecture
@@ -34,8 +38,12 @@ class Gimei::Address
34
38
  @prefectures[2]
35
39
  end
36
40
 
41
+ def romaji
42
+ Romaji.kana2romaji(hiragana).capitalize
43
+ end
44
+
37
45
  def initialize
38
- @prefectures = Gimei::ADDRESSES['addresses']['prefecture'].sample
46
+ @prefectures = Gimei.addresses['addresses']['prefecture'].sample(random: Gimei.config.rng)
39
47
  end
40
48
 
41
49
  alias_method :to_s, :kanji
@@ -54,8 +62,12 @@ class Gimei::Address
54
62
  @cities[2]
55
63
  end
56
64
 
65
+ def romaji
66
+ Romaji.kana2romaji(hiragana).capitalize
67
+ end
68
+
57
69
  def initialize
58
- @cities = Gimei::ADDRESSES['addresses']['city'].sample
70
+ @cities = Gimei.addresses['addresses']['city'].sample(random: Gimei.config.rng)
59
71
  end
60
72
 
61
73
  alias_method :to_s, :kanji
@@ -74,8 +86,12 @@ class Gimei::Address
74
86
  @towns[2]
75
87
  end
76
88
 
89
+ def romaji
90
+ Romaji.kana2romaji(hiragana).capitalize
91
+ end
92
+
77
93
  def initialize
78
- @towns = Gimei::ADDRESSES['addresses']['town'].sample
94
+ @towns = Gimei.addresses['addresses']['town'].sample(random: Gimei.config.rng)
79
95
  end
80
96
 
81
97
  alias_method :to_s, :kanji
@@ -0,0 +1,9 @@
1
+ class Gimei
2
+ class Config
3
+ attr_accessor :rng
4
+
5
+ def initialize(rng: Random.new)
6
+ @rng = rng
7
+ end
8
+ end
9
+ end
data/lib/gimei/name.rb CHANGED
@@ -1,9 +1,10 @@
1
+ require 'romaji'
2
+
1
3
  class Gimei::Name
2
- attr_reader :first, :last
4
+ attr_reader :first, :last, :gender
3
5
 
4
6
  class << self
5
7
  extend Forwardable
6
- def_delegators :new, :kanji, :hiragana, :katakana, :first, :last
7
8
 
8
9
  def male
9
10
  new(:male)
@@ -12,10 +13,16 @@ class Gimei::Name
12
13
  def female
13
14
  new(:female)
14
15
  end
16
+
17
+ %i[kanji hiragana katakana romaji first last].each do |method_name|
18
+ define_method(method_name) do |gender = nil|
19
+ new(gender).public_send(method_name)
20
+ end
21
+ end
15
22
  end
16
23
 
17
24
  def initialize(gender = nil)
18
- @gender = gender || Gimei::GENDER.sample
25
+ @gender = gender || Gimei::GENDERS.sample(random: Gimei.config.rng)
19
26
  @first = First.new @gender
20
27
  @last = Last.new
21
28
  end
@@ -32,6 +39,10 @@ class Gimei::Name
32
39
  "#{last.katakana} #{first.katakana}"
33
40
  end
34
41
 
42
+ def romaji
43
+ "#{first.romaji} #{last.romaji}"
44
+ end
45
+
35
46
  def male?
36
47
  @gender == :male
37
48
  end
@@ -53,9 +64,12 @@ class Gimei::Name
53
64
  end
54
65
  end
55
66
 
67
+ extend Forwardable
68
+ def_delegators :@name, :kanji, :hiragana, :katakana, :to_s, :romaji
69
+
56
70
  def initialize(gender = nil)
57
- @gender = gender || Gimei::GENDER.sample
58
- @name = Gimei::NAMES['first_name'][@gender.to_s].sample
71
+ @gender = gender || Gimei::GENDERS.sample(random: Gimei.config.rng)
72
+ @name = NameWord.new(Gimei.names['first_name'][@gender.to_s].sample(random: Gimei.config.rng))
59
73
  end
60
74
 
61
75
  def male?
@@ -65,25 +79,20 @@ class Gimei::Name
65
79
  def female?
66
80
  @gender == :female
67
81
  end
82
+ end
68
83
 
69
- def kanji
70
- @name[0]
71
- end
72
-
73
- def hiragana
74
- @name[1]
75
- end
84
+ class Last
85
+ extend Forwardable
86
+ def_delegators :@name, :kanji, :hiragana, :katakana, :to_s, :romaji
76
87
 
77
- def katakana
78
- @name[2]
88
+ def initialize
89
+ @name = NameWord.new(Gimei.names['last_name'].sample(random: Gimei.config.rng))
79
90
  end
80
-
81
- alias_method :to_s, :kanji
82
91
  end
83
92
 
84
- class Last
85
- def initialize
86
- @name = Gimei::NAMES['last_name'].sample
93
+ class NameWord
94
+ def initialize(name)
95
+ @name = name
87
96
  end
88
97
 
89
98
  def kanji
@@ -98,6 +107,10 @@ class Gimei::Name
98
107
  @name[2]
99
108
  end
100
109
 
110
+ def romaji
111
+ Romaji.kana2romaji(hiragana).capitalize
112
+ end
113
+
101
114
  alias_method :to_s, :kanji
102
115
  end
103
116
  end
@@ -0,0 +1,47 @@
1
+ class Gimei
2
+ class RetryLimitExceeded < StandardError; end
3
+
4
+ class UniqueGenerator
5
+ class << self
6
+ def previous_results
7
+ @previous_results ||= Hash.new { |hash, key| hash[key] = Set.new }
8
+ end
9
+ end
10
+
11
+ def initialize(klass, max_retries)
12
+ @klass = klass
13
+ @max_retries = max_retries
14
+ end
15
+
16
+ def previous_results
17
+ self.class.previous_results
18
+ end
19
+
20
+ def clear(key = nil)
21
+ if key
22
+ previous_results[key.to_sym].clear
23
+ else
24
+ previous_results.clear
25
+ end
26
+ end
27
+
28
+ def define_unique_method(method_name, previous_result_key = method_name)
29
+ define_singleton_method method_name do |*args|
30
+ max_retries.times do
31
+ result = klass.public_send(method_name, *args)
32
+
33
+ next if previous_results[previous_result_key].include?(result.to_s)
34
+
35
+ previous_results[previous_result_key] << result.to_s
36
+ return result
37
+ end
38
+
39
+ raise RetryLimitExceeded, "Retry limit exceeded for #{method_name}"
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :klass, :max_retries
46
+ end
47
+ end
data/lib/gimei/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Gimei
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/spec/address_spec.rb CHANGED
@@ -2,45 +2,63 @@
2
2
  require_relative 'spec_helper'
3
3
 
4
4
  describe Gimei do
5
+ describe '#kanji and #to_s' do
6
+ it '全角文字が返ること' do
7
+ _(Gimei.address.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
8
+ _(Gimei.address.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
9
+ _(Gimei.address.prefecture.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
10
+ _(Gimei.address.prefecture.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
11
+ _(Gimei.address.city.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
12
+ _(Gimei.address.city.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
13
+ _(Gimei.address.town.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
14
+ _(Gimei.address.town.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
5
15
 
6
- it '全角文字が返ること' do
7
- Gimei.address.kanji.must_match /\A[#{Moji.zen}]+\z/
8
- Gimei.address.to_s.must_match /\A[#{Moji.zen}]+\z/
9
- Gimei.address.prefecture.kanji.must_match /\A[#{Moji.zen}]+\z/
10
- Gimei.address.prefecture.to_s.must_match /\A[#{Moji.zen}]+\z/
11
- Gimei.address.city.kanji.must_match /\A[#{Moji.zen}]+\z/
12
- Gimei.address.city.to_s.must_match /\A[#{Moji.zen}]+\z/
13
- Gimei.address.town.kanji.must_match /\A[#{Moji.zen}]+\z/
14
- Gimei.address.town.to_s.must_match /\A[#{Moji.zen}]+\z/
15
-
16
- Gimei.prefecture.kanji.must_match /\A[#{Moji.zen}]+\z/
17
- Gimei.prefecture.to_s.must_match /\A[#{Moji.zen}]+\z/
18
- Gimei.city.kanji.must_match /\A[#{Moji.zen}]+\z/
19
- Gimei.city.to_s.must_match /\A[#{Moji.zen}]+\z/
20
- Gimei.town.kanji.must_match /\A[#{Moji.zen}]+\z/
21
- Gimei.town.to_s.must_match /\A[#{Moji.zen}]+\z/
16
+ _(Gimei.prefecture.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
17
+ _(Gimei.prefecture.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
18
+ _(Gimei.city.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
19
+ _(Gimei.city.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
20
+ _(Gimei.town.kanji).must_match(/\A#{zenkaku_regexp}+\z/)
21
+ _(Gimei.town.to_s).must_match(/\A#{zenkaku_regexp}+\z/)
22
+ end
22
23
  end
23
24
 
24
- it 'ひらがなが返ること' do
25
- Gimei.address.hiragana.must_match /\A[\p{hiragana}]+\z/
26
- Gimei.address.prefecture.hiragana.must_match /\A[\p{hiragana}]+\z/
27
- Gimei.address.city.hiragana.must_match /\A[\p{hiragana}]+\z/
28
- Gimei.address.town.hiragana.must_match /\A[\p{hiragana}]+\z/
25
+ describe '#hiragana' do
26
+ it 'ひらがなが返ること' do
27
+ _(Gimei.address.hiragana).must_match(/\A[\p{hiragana}]+\z/)
28
+ _(Gimei.address.prefecture.hiragana).must_match(/\A[\p{hiragana}]+\z/)
29
+ _(Gimei.address.city.hiragana).must_match(/\A[\p{hiragana}]+\z/)
30
+ _(Gimei.address.town.hiragana).must_match(/\A[\p{hiragana}]+\z/)
29
31
 
30
- Gimei.prefecture.hiragana.must_match /\A[\p{hiragana}]+\z/
31
- Gimei.city.hiragana.must_match /\A[\p{hiragana}]+\z/
32
- Gimei.town.hiragana.must_match /\A[\p{hiragana}]+\z/
32
+ _(Gimei.prefecture.hiragana).must_match(/\A[\p{hiragana}]+\z/)
33
+ _(Gimei.city.hiragana).must_match(/\A[\p{hiragana}]+\z/)
34
+ _(Gimei.town.hiragana).must_match(/\A[\p{hiragana}]+\z/)
35
+ end
33
36
  end
34
37
 
35
- it 'カタカナが返ること' do
36
- Gimei.address.katakana.must_match /\A[\p{katakana}]+\z/
37
- Gimei.address.prefecture.katakana.must_match /\A[\p{katakana}]+\z/
38
- Gimei.address.city.katakana.must_match /\A[\p{katakana}]+\z/
39
- Gimei.address.town.katakana.must_match /\A[\p{katakana}]+\z/
38
+ describe '#katakana' do
39
+ it 'カタカナが返ること' do
40
+ _(Gimei.address.katakana).must_match(/\A[\p{katakana}]+\z/)
41
+ _(Gimei.address.prefecture.katakana).must_match(/\A[\p{katakana}]+\z/)
42
+ _(Gimei.address.city.katakana).must_match(/\A[\p{katakana}]+\z/)
43
+ _(Gimei.address.town.katakana).must_match(/\A[\p{katakana}]+\z/)
40
44
 
41
- Gimei.prefecture.katakana.must_match /\A[\p{katakana}]+\z/
42
- Gimei.city.katakana.must_match /\A[\p{katakana}]+\z/
43
- Gimei.town.katakana.must_match /\A[\p{katakana}]+\z/
45
+ _(Gimei.prefecture.katakana).must_match(/\A[\p{katakana}]+\z/)
46
+ _(Gimei.city.katakana).must_match(/\A[\p{katakana}]+\z/)
47
+ _(Gimei.town.katakana).must_match(/\A[\p{katakana}]+\z/)
48
+ end
44
49
  end
45
50
 
51
+ describe '#romaji' do
52
+ it 'ローマ字が返ること' do
53
+ _(Gimei.address.romaji).must_match(/\A[a-zA-Z\s]+\z/)
54
+
55
+ _(Gimei.address.prefecture.romaji).must_match(/\A[a-zA-Z]+\z/)
56
+ _(Gimei.address.city.romaji).must_match(/\A[a-zA-Z]+\z/)
57
+ _(Gimei.address.town.romaji).must_match(/\A[a-zA-Z]+\z/)
58
+
59
+ _(Gimei.prefecture.romaji).must_match(/\A[a-zA-Z]+\z/)
60
+ _(Gimei.city.romaji).must_match(/\A[a-zA-Z]+\z/)
61
+ _(Gimei.town.romaji).must_match(/\A[a-zA-Z]+\z/)
62
+ end
63
+ end
46
64
  end
data/spec/gimei_spec.rb CHANGED
@@ -6,11 +6,15 @@ describe Gimei do
6
6
  before { @name = Gimei.male }
7
7
 
8
8
  it 'Gimei::Name オブジェクトが返ること' do
9
- @name.must_be_instance_of Gimei::Name
9
+ _(@name).must_be_instance_of Gimei::Name
10
+ end
11
+
12
+ it '#gender が :male を返すこと' do
13
+ _(@name.gender).must_equal :male
10
14
  end
11
15
 
12
16
  it '#male? が true を返すこと' do
13
- @name.male?.must_equal true
17
+ _(@name.male?).must_equal true
14
18
  end
15
19
  end
16
20
 
@@ -18,137 +22,160 @@ describe Gimei do
18
22
  before { @name = Gimei.female }
19
23
 
20
24
  it 'Gimei::Name オブジェクトが返ること' do
21
- @name.must_be_instance_of Gimei::Name
25
+ _(@name).must_be_instance_of Gimei::Name
26
+ end
27
+
28
+ it '#gender が :female を返すこと' do
29
+ _(@name.gender).must_equal :female
22
30
  end
23
31
 
24
32
  it '#female? が true を返すこと' do
25
- @name.female?.must_equal true
33
+ _(@name.female?).must_equal true
34
+ end
35
+ end
36
+
37
+ describe '#gender' do
38
+ it ':male または :female が返ること' do
39
+ _(Gimei.new.gender).must_be_instance_of(Symbol)
40
+ _(Gimei.new.gender.to_s).must_match(/\A(?:male|female)\Z/)
26
41
  end
27
42
  end
28
43
 
29
44
  describe '#kanji' do
30
45
  it '全角文字とスペースが返ること' do
31
- Gimei.new.kanji.must_match /\A[#{Moji.zen}\s]+\z/
46
+ _(Gimei.new.kanji).must_match(/\A#{zenkaku_or_space_regexp}+\z/)
32
47
  end
33
48
  end
34
49
 
35
50
  describe '#to_s' do
36
51
  it '全角文字とスペースが返ること' do
37
- Gimei.new.to_s.must_match /\A[#{Moji.zen}\s]+\z/
52
+ _(Gimei.new.to_s).must_match(/\A#{zenkaku_or_space_regexp}+\z/)
38
53
  end
39
54
  end
40
55
 
41
56
  describe '.kanji' do
42
57
  it '全角文字とスペースが返ること' do
43
- Gimei.kanji.must_match /\A[#{Moji.zen}\s]+\z/
58
+ _(Gimei.kanji).must_match(/\A#{zenkaku_or_space_regexp}+\z/)
44
59
  end
45
60
  end
46
61
 
47
62
  describe '#hiragana' do
48
63
  it 'ひらがなとスペースが返ること' do
49
- Gimei.new.hiragana.must_match /\A[\p{hiragana}\s]+\z/
64
+ _(Gimei.new.hiragana).must_match(/\A[\p{hiragana}\s]+\z/)
50
65
  end
51
66
  end
52
67
 
53
68
  describe '.hiragana' do
54
69
  it 'ひらがなとスペースが返ること' do
55
- Gimei.hiragana.must_match /\A[\p{hiragana}\s]+\z/
70
+ _(Gimei.hiragana).must_match(/\A[\p{hiragana}\s]+\z/)
56
71
  end
57
72
  end
58
73
 
59
74
  describe '#katakana' do
60
75
  it 'カタカナとスペースが返ること' do
61
- Gimei.new.katakana.must_match /\A[\p{katakana}\s]+\z/
76
+ _(Gimei.new.katakana).must_match(/\A[\p{katakana}\s]+\z/)
62
77
  end
63
78
  end
64
79
 
65
80
  describe '.katakana' do
66
81
  it 'カタカナとスペースが返ること' do
67
- Gimei.katakana.must_match /\A[\p{katakana}\s]+\z/
82
+ _(Gimei.katakana).must_match(/\A[\p{katakana}\s]+\z/)
68
83
  end
69
84
  end
70
85
 
71
86
  describe '.name' do
72
87
  it 'Gimei::Name オブジェクトが返ること' do
73
- Gimei.name.must_be_instance_of Gimei::Name
88
+ _(Gimei.name).must_be_instance_of Gimei::Name
74
89
  end
75
90
  end
76
91
 
77
92
  describe '#name' do
78
93
  it 'Gimei::Name オブジェクトが返ること' do
79
- Gimei.new.name.must_be_instance_of Gimei::Name
94
+ _(Gimei.new.name).must_be_instance_of Gimei::Name
80
95
  end
81
96
  end
82
97
 
83
98
  describe '.first' do
84
99
  it 'Gimei::Name::First オブジェクトが返ること' do
85
- Gimei.first.must_be_instance_of Gimei::Name::First
100
+ _(Gimei.first).must_be_instance_of Gimei::Name::First
86
101
  end
87
102
  end
88
103
 
89
104
  describe '#first' do
90
105
  it 'Gimei::Name::First オブジェクトが返ること' do
91
- Gimei.new.first.must_be_instance_of Gimei::Name::First
106
+ _(Gimei.new.first).must_be_instance_of Gimei::Name::First
92
107
  end
93
108
  end
94
109
 
95
110
  describe '.last' do
96
111
  it 'Gimei::Name::First オブジェクトが返ること' do
97
- Gimei.last.must_be_instance_of Gimei::Name::Last
112
+ _(Gimei.last).must_be_instance_of Gimei::Name::Last
98
113
  end
99
114
  end
100
115
 
101
116
  describe '#last' do
102
117
  it 'Gimei::Name::First オブジェクトが返ること' do
103
- Gimei.new.last.must_be_instance_of Gimei::Name::Last
118
+ _(Gimei.new.last).must_be_instance_of Gimei::Name::Last
119
+ end
120
+ end
121
+
122
+ describe '.romaji' do
123
+ it 'ローマ字とスペースが返ること' do
124
+ _(Gimei.romaji).must_match(/\A[a-zA-Z\s]+\z/)
125
+ end
126
+ end
127
+
128
+ describe '#romaji' do
129
+ it 'ローマ字とスペースが返ること' do
130
+ _(Gimei.new.romaji).must_match(/\A[a-zA-Z\s]+\z/)
104
131
  end
105
132
  end
106
133
 
107
134
  describe '.address' do
108
135
  it 'Gimei::Address オブジェクトが返ること' do
109
- Gimei.address.must_be_instance_of Gimei::Address
136
+ _(Gimei.address).must_be_instance_of Gimei::Address
110
137
  end
111
138
  end
112
139
 
113
140
  describe '#address' do
114
141
  it 'Gimei::Address オブジェクトが返ること' do
115
- Gimei.new.address.must_be_instance_of Gimei::Address
142
+ _(Gimei.new.address).must_be_instance_of Gimei::Address
116
143
  end
117
144
  end
118
145
 
119
146
  describe '.prefecture' do
120
147
  it 'Gimei::Address::Prefecture オブジェクトが返ること' do
121
- Gimei.prefecture.must_be_instance_of Gimei::Address::Prefecture
148
+ _(Gimei.prefecture).must_be_instance_of Gimei::Address::Prefecture
122
149
  end
123
150
  end
124
151
 
125
152
  describe '#prefecture' do
126
153
  it 'Gimei::Address::Prefecture オブジェクトが返ること' do
127
- Gimei.new.prefecture.must_be_instance_of Gimei::Address::Prefecture
154
+ _(Gimei.new.prefecture).must_be_instance_of Gimei::Address::Prefecture
128
155
  end
129
156
  end
130
157
 
131
158
  describe '.city' do
132
159
  it 'Gimei::Address::City オブジェクトが返ること' do
133
- Gimei.city.must_be_instance_of Gimei::Address::City
160
+ _(Gimei.city).must_be_instance_of Gimei::Address::City
134
161
  end
135
162
  end
136
163
 
137
164
  describe '#city' do
138
165
  it 'Gimei::Address::City オブジェクトが返ること' do
139
- Gimei.new.city.must_be_instance_of Gimei::Address::City
166
+ _(Gimei.new.city).must_be_instance_of Gimei::Address::City
140
167
  end
141
168
  end
142
169
 
143
170
  describe '.town' do
144
171
  it 'Gimei::Address::Town オブジェクトが返ること' do
145
- Gimei.town.must_be_instance_of Gimei::Address::Town
172
+ _(Gimei.town).must_be_instance_of Gimei::Address::Town
146
173
  end
147
174
  end
148
175
 
149
176
  describe '#town' do
150
177
  it 'Gimei::Address::Town オブジェクトが返ること' do
151
- Gimei.new.town.must_be_instance_of Gimei::Address::Town
178
+ _(Gimei.new.town).must_be_instance_of Gimei::Address::Town
152
179
  end
153
180
  end
154
181
  end