gimei 0.2.0 → 1.0.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.
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