akm-selectable_attr 0.3.5 → 0.3.7
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/.gitignore +5 -0
- data/MIT-LICENSE +20 -0
- data/README +334 -0
- data/Rakefile +54 -0
- data/VERSION.yml +2 -2
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/selectable_attr/base.rb +4 -5
- data/lib/selectable_attr/enum.rb +8 -1
- data/selectable_attr.gemspec +54 -0
- data/spec/selectable_attr_base_alias_spec.rb +243 -144
- data/spec/selectable_attr_enum_spec.rb +12 -0
- data/tasks/selectable_attr_tasks.rake +18 -0
- data/uninstall.rb +1 -0
- metadata +22 -12
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2008 Takeshi AKIMA
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
= SelectableAttr
|
|
2
|
+
== Introduction
|
|
3
|
+
selectable_attr は、コードが割り振られるような特定の属性について*コード*、*プログラム上での名前*、
|
|
4
|
+
*表示するための名前*などをまとめて管理するものです。
|
|
5
|
+
http://github.com/akm/selectable_attr/tree/master
|
|
6
|
+
|
|
7
|
+
Railsで使用する場合、selectable_attr_railsと一緒に使うことをオススメします。
|
|
8
|
+
http://github.com/akm/selectable_attr_rails/tree/master
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
== Install
|
|
12
|
+
=== 1. Railsプロジェクトで使う場合
|
|
13
|
+
==== a. plugin install
|
|
14
|
+
ruby script/plugin install git://github.com/akm/selectable_attr.git
|
|
15
|
+
ruby script/plugin install git://github.com/akm/selectable_attr_rails.git
|
|
16
|
+
|
|
17
|
+
==== b. gem install
|
|
18
|
+
[sudo] gem install akimatter-selectable_attr akimatter-selectable_attr_rails -s http://gems.github .com
|
|
19
|
+
|
|
20
|
+
=== 2. 非Railsで使う場合
|
|
21
|
+
==== a. gem install
|
|
22
|
+
[sudo] gem install akimatter-selectable_attr -s http://gems.github .com
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
== Tutorial
|
|
27
|
+
|
|
28
|
+
=== シンプルなパターン
|
|
29
|
+
require 'rubygems'
|
|
30
|
+
require 'selectable_attr'
|
|
31
|
+
|
|
32
|
+
class Person
|
|
33
|
+
include ::SelectableAttr::Base
|
|
34
|
+
|
|
35
|
+
selectable_attr :gender do
|
|
36
|
+
entry '1', :male, '男性'
|
|
37
|
+
entry '2', :female, '女性'
|
|
38
|
+
entry '9', :other, 'その他'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
上記のようなクラスがあった場合、以下のようなクラスメソッドを使うことが可能です。
|
|
43
|
+
|
|
44
|
+
irb(main):020:0> Person.gender_ids
|
|
45
|
+
=> ["1", "2", "9"]
|
|
46
|
+
irb(main):021:0> Person.gender_keys
|
|
47
|
+
=> [:male, :female, :other]
|
|
48
|
+
irb(main):022:0> Person.gender_names
|
|
49
|
+
=> ["男性", "女性", "その他"]
|
|
50
|
+
irb(main):023:0> Person.gender_options
|
|
51
|
+
=> [["男性", "1"], ["女性", "2"], ["その他", "9"]] # railsでoptions_for_selectメソッドなどに使えます。
|
|
52
|
+
irb(main):024:0> Person.gender_key_by_id("1")
|
|
53
|
+
=> :male
|
|
54
|
+
irb(main):025:0> Person.gender_name_by_id("1")
|
|
55
|
+
=> "男性"
|
|
56
|
+
irb(main):026:0> Person.gender_id_by_key(:male) # 特定のキーから対応するidを取得できます。
|
|
57
|
+
=> "1"
|
|
58
|
+
irb(main):027:0> Person.gender_name_by_key(:male)
|
|
59
|
+
=> "男性"
|
|
60
|
+
|
|
61
|
+
また使用可能なインスタンスメソッドには以下のようなものがあります。
|
|
62
|
+
|
|
63
|
+
irb> person = Person.new
|
|
64
|
+
=> #<Person:0x133b9d0>
|
|
65
|
+
irb> person.gender_key
|
|
66
|
+
=> nil
|
|
67
|
+
irb> person.gender_name
|
|
68
|
+
=> nil
|
|
69
|
+
irb> person.gender = "2"
|
|
70
|
+
=> "2"
|
|
71
|
+
irb> person.gender_key
|
|
72
|
+
=> :female
|
|
73
|
+
irb> person.gender_name
|
|
74
|
+
=> "女性"
|
|
75
|
+
irb> person.gender_key = :other
|
|
76
|
+
=> :other
|
|
77
|
+
irb> person.gender
|
|
78
|
+
=> "9"
|
|
79
|
+
irb> person.gender_name
|
|
80
|
+
=> "その他"
|
|
81
|
+
|
|
82
|
+
genderが代入可能なことはもちろん、gender_keyも代入可能です。
|
|
83
|
+
# ただし、gender_nameには代入できません。
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
=== 複数の値を取りうるパターン
|
|
87
|
+
require 'rubygems'
|
|
88
|
+
require 'selectable_attr'
|
|
89
|
+
|
|
90
|
+
class RoomSearch
|
|
91
|
+
include ::SelectableAttr::Base
|
|
92
|
+
|
|
93
|
+
multi_selectable_attr :room_type do
|
|
94
|
+
entry '01', :single, 'シングル'
|
|
95
|
+
entry '02', :twin, 'ツイン'
|
|
96
|
+
entry '03', :double, 'ダブル'
|
|
97
|
+
entry '04', :triple, 'トリプル'
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
multi_selectable_attrを使った場合に使用できるクラスメソッドは、selectable_attrの場合と同じです。
|
|
102
|
+
|
|
103
|
+
irb> room_search = RoomSearch.new
|
|
104
|
+
=> #<RoomSearch:0x134a070>
|
|
105
|
+
irb> room_search.room_type_ids
|
|
106
|
+
=> []
|
|
107
|
+
irb> room_search.room_type_keys
|
|
108
|
+
=> []
|
|
109
|
+
irb> room_search.room_type_names
|
|
110
|
+
=> []
|
|
111
|
+
irb> room_search.room_type_selection
|
|
112
|
+
=> [false, false, false, false]
|
|
113
|
+
irb> room_search.room_type_keys = [:twin, :double]
|
|
114
|
+
=> [:twin, :double]
|
|
115
|
+
irb> room_search.room_type
|
|
116
|
+
=> ["02", "03"]
|
|
117
|
+
irb> room_search.room_type_names
|
|
118
|
+
=> ["ツイン", "ダブル"]
|
|
119
|
+
irb> room_search.room_type_ids
|
|
120
|
+
=> ["02", "03"]
|
|
121
|
+
irb> room_search.room_type = ["01", "04"]
|
|
122
|
+
=> ["01", "04"]
|
|
123
|
+
irb> room_search.room_type_keys
|
|
124
|
+
=> [:single, :triple]
|
|
125
|
+
irb> room_search.room_type_names
|
|
126
|
+
=> ["シングル", "トリプル"]
|
|
127
|
+
irb> room_search.room_type_selection
|
|
128
|
+
=> [true, false, false, true]
|
|
129
|
+
irb> room_search.room_type_hash_array
|
|
130
|
+
=> [{:select=>true, :key=>:single, :name=>"シングル", :id=>"01"}, {:select=>false, :key=>:twin, :name=>"ツイン", :id=>"02"}, {:select=>false, :key=>:double, :name=>"ダブル", :id=>"03"}, {:select=>true, :key=>:triple, :name=>"トリプル", :id=>"04"}]
|
|
131
|
+
irb> room_search.room_type_hash_array_selected
|
|
132
|
+
=> [{:select=>true, :key=>:single, :name=>"シングル", :id=>"01"}, {:select=>true, :key=>:triple, :name=>"トリプル", :id=>"04"}]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
=== Entry
|
|
137
|
+
==== エントリの取得
|
|
138
|
+
エントリは様々な拡張が可能です。例えば以下のようにid、key、name以外の属性を設定することも可能です。
|
|
139
|
+
|
|
140
|
+
require 'rubygems'
|
|
141
|
+
require 'selectable_attr'
|
|
142
|
+
|
|
143
|
+
class Site
|
|
144
|
+
include ::SelectableAttr::Base
|
|
145
|
+
|
|
146
|
+
selectable_attr :protocol do
|
|
147
|
+
entry '01', :http , 'HTTP' , :port => 80
|
|
148
|
+
entry '02', :https, 'HTTPS' , :port => 443
|
|
149
|
+
entry '03', :ssh , 'SSH' , :port => 22
|
|
150
|
+
entry '04', :svn , 'Subversion', :port => 3690
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
クラスメソッドで各エントリを取得することが可能です。
|
|
155
|
+
entry = Site.protocol_entry_by_key(:https)
|
|
156
|
+
entry = Site.protocol_entry_by_id('02')
|
|
157
|
+
|
|
158
|
+
インスタンスメソッドでは以下のように取得できます。
|
|
159
|
+
site = Site.new
|
|
160
|
+
site.protocol_key = :https
|
|
161
|
+
entry = site.protocol_entry
|
|
162
|
+
|
|
163
|
+
==== エントリの属性
|
|
164
|
+
id, key, nameもそのままメソッドとして用意されています。
|
|
165
|
+
irb> entry.id
|
|
166
|
+
=> "02"
|
|
167
|
+
irb> entry.key
|
|
168
|
+
=> :https
|
|
169
|
+
irb> entry.name
|
|
170
|
+
=> "HTTPS"
|
|
171
|
+
|
|
172
|
+
またオプションの属性もHashのようにアクセス可能です。
|
|
173
|
+
irb> entry[:port]
|
|
174
|
+
=> 443
|
|
175
|
+
|
|
176
|
+
to_hashメソッドで、id, key, nameを含むHashを作成します。
|
|
177
|
+
irb> entry.to_hash
|
|
178
|
+
=> {:key=>:https, :port=>443, :name=>"HTTPS", :id=>"02"}
|
|
179
|
+
|
|
180
|
+
matchメソッドでid,key,nameを除くオプションの属性群と一致しているかどうかを判断可能です。
|
|
181
|
+
|
|
182
|
+
irb> entry.match?(:port => 22)
|
|
183
|
+
=> false
|
|
184
|
+
irb> entry.match?(:port => 443)
|
|
185
|
+
=> true
|
|
186
|
+
|
|
187
|
+
# ここではオプションの属性として:portしか設定していないので、matchに渡すHashのキーと値の組み合わせも一つだけですが、
|
|
188
|
+
# 複数ある場合にmatch?がtrueとなるためには、完全に一致している必要があります。
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
==== クラスメソッドでのエントリの扱い
|
|
192
|
+
クラスメソッドでエントリを取得する方法として、xxx_entry_by_id, xxx_entry_by_keyを紹介しましたが、
|
|
193
|
+
全てのエントリで構成される配列を取得するメソッドが xxx_entriesです。
|
|
194
|
+
|
|
195
|
+
irb> entries = Site.protocol_entries
|
|
196
|
+
irb> entries.length
|
|
197
|
+
=> 4
|
|
198
|
+
|
|
199
|
+
また、各エントリをto_hashでHashに変換した配列を xxx_hash_arrayメソッドで取得することも可能です。
|
|
200
|
+
irb> Site.protocol_hash_array
|
|
201
|
+
=> [
|
|
202
|
+
{:key=>:http, :port=>80, :name=>"HTTP", :id=>"01"},
|
|
203
|
+
{:key=>:https, :port=>443, :name=>"HTTPS", :id=>"02"},
|
|
204
|
+
{:key=>:ssh, :port=>22, :name=>"SSH", :id=>"03"},
|
|
205
|
+
{:key=>:svn, :port=>3690, :name=>"Subversion", :id=>"04"}
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
=== Enum
|
|
210
|
+
あまり表にでてきませんが、エントリをまとめる役割のオブジェクトがEnumです。
|
|
211
|
+
これはクラスメソッドxxx_enumで取得することができます。
|
|
212
|
+
|
|
213
|
+
irb> enum = Site.protocol_enum
|
|
214
|
+
|
|
215
|
+
Enumには以下のようなメソッドが用意されています。
|
|
216
|
+
irb> enum.entries
|
|
217
|
+
irb> enum.entries.map{|entry| entry[:port]}
|
|
218
|
+
=> [80, 443, 22, 3690]
|
|
219
|
+
|
|
220
|
+
EnumはEnumerableをincludeしているため、以下のように記述することも可能です。
|
|
221
|
+
irb> enum.map{|entry| entry[:port]}
|
|
222
|
+
=> [80, 443, 22, 3690]
|
|
223
|
+
|
|
224
|
+
irb> enum.entry_by_id("03")
|
|
225
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
226
|
+
irb> enum.entry_by_key(:ssh)
|
|
227
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
228
|
+
irb> enum.entry_by_id_or_key(:ssh)
|
|
229
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
230
|
+
irb> enum.entry_by_id_or_key('03')
|
|
231
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
232
|
+
irb> enum.entry_by_hash(:port => 22)
|
|
233
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
234
|
+
|
|
235
|
+
また、これらのメソッドが面倒と感じるようであれば、以下のような簡単なアクセスも可能です。
|
|
236
|
+
irb> enum['03']
|
|
237
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
238
|
+
irb> enum[:ssh]
|
|
239
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
240
|
+
irb> enum[:port => 22]
|
|
241
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
242
|
+
|
|
243
|
+
またクラスメソッドで紹介したようなxxx_ids, xxx_keys, xxx_namesや、xxx_key_by_idなどのメソッドも用意されています。
|
|
244
|
+
irb> enum.ids
|
|
245
|
+
=> ["01", "02", "03", "04"]
|
|
246
|
+
irb> enum.keys
|
|
247
|
+
=> [:http, :https, :ssh, :svn]
|
|
248
|
+
irb> enum.names
|
|
249
|
+
=> ["HTTP", "HTTPS", "SSH", "Subversion"]
|
|
250
|
+
irb> enum.options
|
|
251
|
+
=> [["HTTP", "01"], ["HTTPS", "02"], ["SSH", "03"], ["Subversion", "04"]]
|
|
252
|
+
irb> enum.key_by_id('04')
|
|
253
|
+
=> :svn
|
|
254
|
+
irb> enum.id_by_key(:svn)
|
|
255
|
+
=> "04"
|
|
256
|
+
irb> enum.name_by_id('04')
|
|
257
|
+
=> "Subversion"
|
|
258
|
+
irb> enum.name_by_key(:svn)
|
|
259
|
+
=> "Subversion"
|
|
260
|
+
irb> enum.to_hash_array
|
|
261
|
+
=> [
|
|
262
|
+
{:key=>:http, :port=>80, :name=>"HTTP", :id=>"01"},
|
|
263
|
+
{:key=>:https, :port=>443, :name=>"HTTPS", :id=>"02"},
|
|
264
|
+
{:key=>:ssh, :port=>22, :name=>"SSH", :id=>"03"},
|
|
265
|
+
{:key=>:svn, :port=>3690, :name=>"Subversion", :id=>"04"}
|
|
266
|
+
]
|
|
267
|
+
|
|
268
|
+
id, key以外でエントリを特定したい場合はfindメソッドが使えます。
|
|
269
|
+
irb> enum.find(:port => 22)
|
|
270
|
+
=> #<SelectableAttr::Enum::Entry:1352a54 @id="03", @key=:ssh, @name="SSH", @options={:port=>22}
|
|
271
|
+
|
|
272
|
+
findメソッドにはブロックを渡すこともできます。
|
|
273
|
+
irb> enum.find{|entry| entry[:port] > 1024}
|
|
274
|
+
=> #<SelectableAttr::Enum::Entry:1352a04 @id="04", @key=:svn, @name="Subversion", @options={:port=>3690}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
=== Entryへのメソッド定義
|
|
278
|
+
entryメソッドにブロックを渡すとエントリのオブジェクトにメソッドを定義することが可能です。
|
|
279
|
+
|
|
280
|
+
require 'rubygems'
|
|
281
|
+
require 'selectable_attr'
|
|
282
|
+
|
|
283
|
+
class Site
|
|
284
|
+
include ::SelectableAttr::Base
|
|
285
|
+
|
|
286
|
+
selectable_attr :protocol do
|
|
287
|
+
entry '01', :http , 'HTTP', :port => 80 do
|
|
288
|
+
def accept?(model)
|
|
289
|
+
# httpで指定された場合はhttpsも可、という仕様
|
|
290
|
+
model.url =~ /^http[s]{0,1}\:\/\//
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
entry '02', :https, 'HTTPS', :port => 443 do
|
|
295
|
+
def accept?(model)
|
|
296
|
+
model.url =~ /^https\:\/\//
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
entry '03', :ssh , 'SSH', :port => 22 do
|
|
301
|
+
def accept?(model)
|
|
302
|
+
false
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
entry '04', :svn , 'Subversion', :port => 3690 do
|
|
307
|
+
def accept?(model)
|
|
308
|
+
model.url =~ /^svn\:\/\/|^svn+ssh\:\/\//
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
enum = Site.protocol_enum
|
|
316
|
+
|
|
317
|
+
class Project
|
|
318
|
+
attr_accessor :url
|
|
319
|
+
end
|
|
320
|
+
project = Project.new
|
|
321
|
+
project.url = "http://github.com/akm/selectable_attr/tree/master"
|
|
322
|
+
|
|
323
|
+
irb> enum[:http].accept?(project)
|
|
324
|
+
=> 0
|
|
325
|
+
irb> enum[:https].accept?(project)
|
|
326
|
+
=> nil
|
|
327
|
+
|
|
328
|
+
というようにentryメソッドに渡したブロックは、生成されるエントリオブジェクトのコンテキストでinstance_evalされるので、そのメソッドを定義することが可能です。
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
== Credit
|
|
334
|
+
Copyright (c) 2008 Takeshi AKIMA, released under the MIT lice nse
|
data/Rakefile
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
gem 'rspec', '>= 1.1.4'
|
|
3
|
+
require 'rake'
|
|
4
|
+
require 'rake/rdoctask'
|
|
5
|
+
require 'spec/rake/spectask'
|
|
6
|
+
require 'spec/rake/verify_rcov'
|
|
7
|
+
|
|
8
|
+
desc 'Default: run unit tests.'
|
|
9
|
+
task :default => :spec
|
|
10
|
+
|
|
11
|
+
task :pre_commit => [:spec, 'coverage:verify']
|
|
12
|
+
|
|
13
|
+
desc 'Run all specs under spec/**/*_spec.rb'
|
|
14
|
+
Spec::Rake::SpecTask.new(:spec => 'coverage:clean') do |t|
|
|
15
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
16
|
+
t.spec_opts = ["-c", "--diff"]
|
|
17
|
+
t.rcov = true
|
|
18
|
+
t.rcov_opts = ["--include-file", "lib\/*\.rb", "--exclude", "spec\/"]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc 'Generate documentation for the selectable_attr plugin.'
|
|
22
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
23
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
24
|
+
rdoc.title = 'SelectableAttr'
|
|
25
|
+
rdoc.options << '--line-numbers' << '--inline-source' << '-c UTF-8'
|
|
26
|
+
rdoc.rdoc_files.include('README*')
|
|
27
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
namespace :coverage do
|
|
31
|
+
desc "Delete aggregate coverage data."
|
|
32
|
+
task(:clean) { rm_f "coverage" }
|
|
33
|
+
|
|
34
|
+
desc "verify coverage threshold via RCov"
|
|
35
|
+
RCov::VerifyTask.new(:verify => :spec) do |t|
|
|
36
|
+
t.threshold = 100.0 # Make sure you have rcov 0.7 or higher!
|
|
37
|
+
t.index_html = 'coverage/index.html'
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
require 'jeweler'
|
|
43
|
+
Jeweler::Tasks.new do |s|
|
|
44
|
+
s.name = "selectable_attr"
|
|
45
|
+
s.summary = "selectable_attr generates extra methods dynamically"
|
|
46
|
+
s.description = "selectable_attr generates extra methods dynamically for attribute which has options"
|
|
47
|
+
s.email = "akima@gmail.com"
|
|
48
|
+
s.homepage = "http://github.com/akm/selectable_attr/"
|
|
49
|
+
s.authors = ["Takeshi Akima"]
|
|
50
|
+
end
|
|
51
|
+
rescue LoadError
|
|
52
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
|
53
|
+
end
|
|
54
|
+
|
data/VERSION.yml
CHANGED
data/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'selectable_attr'
|
data/install.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Install hook code here
|
data/lib/selectable_attr/base.rb
CHANGED
|
@@ -68,8 +68,8 @@ module SelectableAttr
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def selectable_attr_type_for(attr)
|
|
71
|
-
single_selectable_attrs.include?(attr) ? :single :
|
|
72
|
-
multi_selectable_attrs.include?(attr) ? :multi : nil
|
|
71
|
+
single_selectable_attrs.include?(attr.to_s) ? :single :
|
|
72
|
+
multi_selectable_attrs.include?(attr.to_s) ? :multi : nil
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def enum(*args, &block)
|
|
@@ -168,7 +168,8 @@ module SelectableAttr
|
|
|
168
168
|
|
|
169
169
|
def enum_for(attr)
|
|
170
170
|
base_name = enum_base_name(attr)
|
|
171
|
-
|
|
171
|
+
name = "#{base_name.upcase}_ENUM"
|
|
172
|
+
const_defined?(name) ? const_get(name) : nil
|
|
172
173
|
end
|
|
173
174
|
|
|
174
175
|
def define_accessor(context)
|
|
@@ -261,8 +262,6 @@ module SelectableAttr
|
|
|
261
262
|
ids = ids ? ids.map(&:to_s) : []
|
|
262
263
|
update_#{base_name}_hash_array{|hash|ids.include?(hash[:id].to_s)}
|
|
263
264
|
end
|
|
264
|
-
EOS
|
|
265
|
-
self.module_eval(<<-"EOS")
|
|
266
265
|
def #{base_name}_hash_array
|
|
267
266
|
self.class.#{base_name}_to_hash_array(self.class.#{base_name}_enum, #{attr})
|
|
268
267
|
end
|
data/lib/selectable_attr/enum.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
module SelectableAttr
|
|
2
3
|
|
|
3
4
|
class Enum
|
|
@@ -149,7 +150,13 @@ module SelectableAttr
|
|
|
149
150
|
def to_hash
|
|
150
151
|
(@options || {}).merge(:id => @id, :key => @key, :name => name)
|
|
151
152
|
end
|
|
152
|
-
|
|
153
|
+
|
|
154
|
+
def inspect
|
|
155
|
+
# object_idを2倍にしているのは通常のinspectと合わせるためです。
|
|
156
|
+
'#<%s:%x @id=%s, @key=%s, @name=%s, @options=%s' % [
|
|
157
|
+
self.class.name, object_id * 2, id.inspect, key.inspect, name.inspect, @options.inspect]
|
|
158
|
+
end
|
|
159
|
+
|
|
153
160
|
NULL = new(nil, nil, nil, nil) do
|
|
154
161
|
def null?; true; end
|
|
155
162
|
def name; nil; end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = %q{selectable_attr}
|
|
5
|
+
s.version = "0.3.7"
|
|
6
|
+
|
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
8
|
+
s.authors = ["Takeshi Akima"]
|
|
9
|
+
s.date = %q{2009-08-17}
|
|
10
|
+
s.description = %q{selectable_attr generates extra methods dynamically for attribute which has options}
|
|
11
|
+
s.email = %q{akima@gmail.com}
|
|
12
|
+
s.extra_rdoc_files = [
|
|
13
|
+
"README"
|
|
14
|
+
]
|
|
15
|
+
s.files = [
|
|
16
|
+
".gitignore",
|
|
17
|
+
"MIT-LICENSE",
|
|
18
|
+
"README",
|
|
19
|
+
"Rakefile",
|
|
20
|
+
"VERSION.yml",
|
|
21
|
+
"init.rb",
|
|
22
|
+
"install.rb",
|
|
23
|
+
"lib/selectable_attr.rb",
|
|
24
|
+
"lib/selectable_attr/base.rb",
|
|
25
|
+
"lib/selectable_attr/enum.rb",
|
|
26
|
+
"lib/selectable_attr/version.rb",
|
|
27
|
+
"selectable_attr.gemspec",
|
|
28
|
+
"spec/selectable_attr_base_alias_spec.rb",
|
|
29
|
+
"spec/selectable_attr_enum_spec.rb",
|
|
30
|
+
"spec/spec_helper.rb",
|
|
31
|
+
"tasks/selectable_attr_tasks.rake",
|
|
32
|
+
"uninstall.rb"
|
|
33
|
+
]
|
|
34
|
+
s.homepage = %q{http://github.com/akm/selectable_attr/}
|
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
36
|
+
s.require_paths = ["lib"]
|
|
37
|
+
s.rubygems_version = %q{1.3.4}
|
|
38
|
+
s.summary = %q{selectable_attr generates extra methods dynamically}
|
|
39
|
+
s.test_files = [
|
|
40
|
+
"spec/selectable_attr_base_alias_spec.rb",
|
|
41
|
+
"spec/selectable_attr_enum_spec.rb",
|
|
42
|
+
"spec/spec_helper.rb"
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
if s.respond_to? :specification_version then
|
|
46
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
47
|
+
s.specification_version = 3
|
|
48
|
+
|
|
49
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
50
|
+
else
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -70,66 +70,72 @@ describe SelectableAttr do
|
|
|
70
70
|
include ::SelectableAttr::Base
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class EnumMock1WithEnum < EnumBase
|
|
82
|
-
selectable_attr :enum1, :default => 2 do
|
|
83
|
-
entry 1, :entry1, "エントリ1"
|
|
84
|
-
entry 2, :entry2, "エントリ2"
|
|
85
|
-
entry 3, :entry3, "エントリ3"
|
|
73
|
+
describe "selectable_attr with default" do
|
|
74
|
+
class EnumMock1 < EnumBase
|
|
75
|
+
selectable_attr :enum1, :default => 2 do
|
|
76
|
+
entry 1, :entry1, "エントリ1"
|
|
77
|
+
entry 2, :entry2, "エントリ2"
|
|
78
|
+
entry 3, :entry3, "エントリ3"
|
|
79
|
+
end
|
|
86
80
|
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "test_selectable_attr1" do
|
|
90
|
-
assert_enum_class_methods(EnumMock1)
|
|
91
|
-
mock1 = EnumMock1.new
|
|
92
|
-
mock1.enum1.should == 2
|
|
93
|
-
assert_single_enum_instance_methods(mock1)
|
|
94
|
-
|
|
95
|
-
assert_enum_class_methods(EnumMock1WithEnum)
|
|
96
|
-
mock1 = EnumMock1WithEnum.new
|
|
97
|
-
mock1.enum1.should == 2
|
|
98
|
-
assert_single_enum_instance_methods(mock1)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
81
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
82
|
+
class EnumMock1WithEnum < EnumBase
|
|
83
|
+
selectable_attr :enum1, :default => 2 do
|
|
84
|
+
entry 1, :entry1, "エントリ1"
|
|
85
|
+
entry 2, :entry2, "エントリ2"
|
|
86
|
+
entry 3, :entry3, "エントリ3"
|
|
87
|
+
end
|
|
105
88
|
end
|
|
106
89
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
90
|
+
it "test_selectable_attr1" do
|
|
91
|
+
assert_enum_class_methods(EnumMock1)
|
|
92
|
+
mock1 = EnumMock1.new
|
|
93
|
+
mock1.enum1.should == 2
|
|
94
|
+
assert_single_enum_instance_methods(mock1)
|
|
95
|
+
|
|
96
|
+
assert_enum_class_methods(EnumMock1WithEnum)
|
|
97
|
+
mock1 = EnumMock1WithEnum.new
|
|
98
|
+
mock1.enum1.should == 2
|
|
99
|
+
assert_single_enum_instance_methods(mock1)
|
|
100
|
+
|
|
101
|
+
EnumMock1.selectable_attr_type_for(:enum1).should == :single
|
|
102
|
+
EnumMock1WithEnum.selectable_attr_type_for(:enum1).should == :single
|
|
111
103
|
end
|
|
112
104
|
end
|
|
105
|
+
|
|
113
106
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
attr
|
|
107
|
+
describe "attr_enumeable_base" do
|
|
108
|
+
class EnumMock2 < EnumBase
|
|
109
|
+
attr_enumeable_base do |attr|
|
|
110
|
+
attr.to_s.gsub(/(.*)_code(.*)$/){"#{$1}#{$2}"}
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
selectable_attr :enum_code1 do
|
|
114
|
+
entry 1, :entry1, "エントリ1"
|
|
115
|
+
entry 2, :entry2, "エントリ2"
|
|
116
|
+
entry 3, :entry3, "エントリ3"
|
|
117
|
+
end
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
class EnumMock2WithEnum < EnumBase
|
|
121
|
+
attr_enumeable_base do |attr|
|
|
122
|
+
attr.to_s.gsub(/(.*)_code(.*)$/){"#{$1}#{$2}"}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
enum :enum_code1 do
|
|
126
|
+
entry 1, :entry1, "エントリ1"
|
|
127
|
+
entry 2, :entry2, "エントリ2"
|
|
128
|
+
entry 3, :entry3, "エントリ3"
|
|
129
|
+
end
|
|
123
130
|
end
|
|
124
|
-
end
|
|
125
131
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
it "test_selectable_attr2" do
|
|
133
|
+
assert_enum_class_methods(EnumMock2)
|
|
134
|
+
assert_single_enum_instance_methods(EnumMock2.new, :enum_code1)
|
|
135
|
+
assert_enum_class_methods(EnumMock2WithEnum)
|
|
136
|
+
assert_single_enum_instance_methods(EnumMock2WithEnum.new, :enum_code1)
|
|
137
|
+
end
|
|
131
138
|
end
|
|
132
|
-
|
|
133
139
|
|
|
134
140
|
|
|
135
141
|
def assert_multi_enum_instance_methods(obj, patterns)
|
|
@@ -210,122 +216,215 @@ describe SelectableAttr do
|
|
|
210
216
|
obj.enum_array1_ids = "2"; obj.enum_array1.should == patterns[2]
|
|
211
217
|
end
|
|
212
218
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
describe ":convert_with => :binary_string" do
|
|
220
|
+
class EnumMock3 < EnumBase
|
|
221
|
+
multi_selectable_attr :enum_array1, :convert_with => :binary_string do
|
|
222
|
+
entry 1, :entry1, "エントリ1"
|
|
223
|
+
entry 2, :entry2, "エントリ2"
|
|
224
|
+
entry 3, :entry3, "エントリ3"
|
|
225
|
+
end
|
|
218
226
|
end
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
|
|
228
|
+
class EnumMock3WithEnumArray < EnumBase
|
|
229
|
+
enum_array :enum_array1, :convert_with => :binary_string do
|
|
230
|
+
entry 1, :entry1, "エントリ1"
|
|
231
|
+
entry 2, :entry2, "エントリ2"
|
|
232
|
+
entry 3, :entry3, "エントリ3"
|
|
233
|
+
end
|
|
226
234
|
end
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
it "test_multi_selectable_attr_with_binary_string" do
|
|
230
|
-
expected = (0..7).map{|i| '%-03b' % i} # ["000", "001", "010", "011", "100", "101", "110", "111"]
|
|
231
|
-
assert_enum_class_methods(EnumMock3, :enum_array1)
|
|
232
|
-
assert_multi_enum_instance_methods(EnumMock3.new, expected)
|
|
233
|
-
assert_enum_class_methods(EnumMock3WithEnumArray, :enum_array1)
|
|
234
|
-
assert_multi_enum_instance_methods(EnumMock3WithEnumArray.new, expected)
|
|
235
|
-
end
|
|
236
235
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
it "test_multi_selectable_attr_with_binary_string" do
|
|
237
|
+
expected = (0..7).map{|i| '%-03b' % i} # ["000", "001", "010", "011", "100", "101", "110", "111"]
|
|
238
|
+
assert_enum_class_methods(EnumMock3, :enum_array1)
|
|
239
|
+
assert_multi_enum_instance_methods(EnumMock3.new, expected)
|
|
240
|
+
assert_enum_class_methods(EnumMock3WithEnumArray, :enum_array1)
|
|
241
|
+
assert_multi_enum_instance_methods(EnumMock3WithEnumArray.new, expected)
|
|
242
|
+
EnumMock3.selectable_attr_type_for(:enum_array1).should == :multi
|
|
242
243
|
end
|
|
243
244
|
end
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
|
|
246
|
+
describe "multi_selectable_attr" do
|
|
247
|
+
class EnumMock4 < EnumBase
|
|
248
|
+
multi_selectable_attr :enum_array1 do
|
|
249
|
+
entry 1, :entry1, "エントリ1"
|
|
250
|
+
entry 2, :entry2, "エントリ2"
|
|
251
|
+
entry 3, :entry3, "エントリ3"
|
|
252
|
+
end
|
|
250
253
|
end
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
s = '%03b' % i
|
|
258
|
-
a = s.split('').map{|v| v.to_i}
|
|
259
|
-
ret = []
|
|
260
|
-
a.each_with_index{|val, pos| ret << pos + 1 if val == 1}
|
|
261
|
-
ret
|
|
254
|
+
|
|
255
|
+
class EnumMock4WithEnumArray < EnumBase
|
|
256
|
+
enum_array :enum_array1 do
|
|
257
|
+
entry 1, :entry1, "エントリ1"
|
|
258
|
+
entry 2, :entry2, "エントリ2"
|
|
259
|
+
entry 3, :entry3, "エントリ3"
|
|
262
260
|
end
|
|
263
|
-
|
|
264
|
-
assert_multi_enum_instance_methods(EnumMock4.new, expected)
|
|
265
|
-
assert_enum_class_methods(EnumMock4WithEnumArray, :enum_array1)
|
|
266
|
-
assert_multi_enum_instance_methods(EnumMock4WithEnumArray.new, expected)
|
|
267
|
-
end
|
|
261
|
+
end
|
|
268
262
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
263
|
+
it "test_multi_selectable_attr2" do
|
|
264
|
+
# [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
|
|
265
|
+
expected =
|
|
266
|
+
(0..7).map do |i|
|
|
267
|
+
s = '%03b' % i
|
|
268
|
+
a = s.split('').map{|v| v.to_i}
|
|
269
|
+
ret = []
|
|
270
|
+
a.each_with_index{|val, pos| ret << pos + 1 if val == 1}
|
|
271
|
+
ret
|
|
272
|
+
end
|
|
273
|
+
assert_enum_class_methods(EnumMock4, :enum_array1)
|
|
274
|
+
assert_multi_enum_instance_methods(EnumMock4.new, expected)
|
|
275
|
+
assert_enum_class_methods(EnumMock4WithEnumArray, :enum_array1)
|
|
276
|
+
assert_multi_enum_instance_methods(EnumMock4WithEnumArray.new, expected)
|
|
274
277
|
end
|
|
275
278
|
end
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
|
|
280
|
+
describe "convert_with" do
|
|
281
|
+
class EnumMock5 < EnumBase
|
|
282
|
+
multi_selectable_attr :enum_array1, :convert_with => :comma_string do
|
|
283
|
+
entry 1, :entry1, "エントリ1"
|
|
284
|
+
entry 2, :entry2, "エントリ2"
|
|
285
|
+
entry 3, :entry3, "エントリ3"
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
class EnumMock5WithEnumArray < EnumBase
|
|
290
|
+
enum_array :enum_array1, :convert_with => :comma_string do
|
|
291
|
+
entry 1, :entry1, "エントリ1"
|
|
292
|
+
entry 2, :entry2, "エントリ2"
|
|
293
|
+
entry 3, :entry3, "エントリ3"
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it "test_multi_selectable_attr_with_comma_string" do
|
|
298
|
+
# ["", "3", "2", "2,3", "1", "1,3", "1,2", "1,2,3"]
|
|
299
|
+
expected =
|
|
300
|
+
(0..7).map do |i|
|
|
301
|
+
s = '%03b' % i
|
|
302
|
+
a = s.split('').map{|v| v.to_i}
|
|
303
|
+
ret = []
|
|
304
|
+
a.each_with_index{|val, pos| ret << pos + 1 if val == 1}
|
|
305
|
+
ret.join(',')
|
|
306
|
+
end
|
|
307
|
+
assert_enum_class_methods(EnumMock5, :enum_array1)
|
|
308
|
+
assert_multi_enum_instance_methods(EnumMock5.new, expected)
|
|
309
|
+
assert_enum_class_methods(EnumMock5WithEnumArray, :enum_array1)
|
|
310
|
+
assert_multi_enum_instance_methods(EnumMock5WithEnumArray.new, expected)
|
|
282
311
|
end
|
|
283
312
|
end
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
ret = []
|
|
292
|
-
a.each_with_index{|val, pos| ret << pos + 1 if val == 1}
|
|
293
|
-
ret.join(',')
|
|
313
|
+
|
|
314
|
+
describe "selectable_attr_name_pattern" do
|
|
315
|
+
class EnumMock6 < EnumBase
|
|
316
|
+
# self.selectable_attr_name_pattern = /(_cd$|_code$|_cds$|_codes$)/
|
|
317
|
+
selectable_attr :category_id do
|
|
318
|
+
entry "01", :category1, "カテゴリ1"
|
|
319
|
+
entry "02", :category2, "カテゴリ2"
|
|
294
320
|
end
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
class EnumMock7 < EnumBase
|
|
324
|
+
self.selectable_attr_name_pattern = /(_cd$|_id$|_cds$|_ids$)/
|
|
325
|
+
selectable_attr :category_id do
|
|
326
|
+
entry "01", :category1, "カテゴリ1"
|
|
327
|
+
entry "02", :category2, "カテゴリ2"
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
it "test_selectable_attr_name_pattern" do
|
|
332
|
+
EnumMock6.selectable_attr_name_pattern.should == /(_cd$|_code$|_cds$|_codes$)/
|
|
333
|
+
EnumMock6.respond_to?(:category_enum).should == false
|
|
334
|
+
EnumMock6.respond_to?(:category_id_enum).should == true
|
|
335
|
+
EnumMock6.new.respond_to?(:category_key).should == false
|
|
336
|
+
EnumMock6.new.respond_to?(:category_id_key).should == true
|
|
337
|
+
|
|
338
|
+
EnumMock7.selectable_attr_name_pattern.should == /(_cd$|_id$|_cds$|_ids$)/
|
|
339
|
+
EnumMock7.respond_to?(:category_enum).should == true
|
|
340
|
+
EnumMock7.respond_to?(:category_id_enum).should == false
|
|
341
|
+
EnumMock7.new.respond_to?(:category_key).should == true
|
|
342
|
+
EnumMock7.new.respond_to?(:category_id_key).should == false
|
|
343
|
+
end
|
|
299
344
|
end
|
|
345
|
+
|
|
346
|
+
describe "has_attr" do
|
|
347
|
+
class ConnectableMock1 < EnumBase
|
|
348
|
+
class << self
|
|
349
|
+
def columns; end
|
|
350
|
+
def connection; end
|
|
351
|
+
def connectec?; end
|
|
352
|
+
def table_exists?; end
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
it "should return false if column does exist" do
|
|
357
|
+
ConnectableMock1.should_receive(:connected?).and_return(true)
|
|
358
|
+
ConnectableMock1.should_receive(:table_exists?).and_return(true)
|
|
359
|
+
ConnectableMock1.should_receive(:columns).and_return([mock(:column1, :name => :column1)])
|
|
360
|
+
ConnectableMock1.has_attr(:column1).should == true
|
|
361
|
+
end
|
|
300
362
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
363
|
+
it "should return false if column doesn't exist" do
|
|
364
|
+
ConnectableMock1.should_receive(:connected?).and_return(true)
|
|
365
|
+
ConnectableMock1.should_receive(:table_exists?).and_return(true)
|
|
366
|
+
ConnectableMock1.should_receive(:columns).and_return([mock(:column1, :name => :column1)])
|
|
367
|
+
ConnectableMock1.has_attr(:unknown_column).should == false
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
it "should return nil unless connected" do
|
|
371
|
+
ConnectableMock1.should_receive(:connected?).and_return(false)
|
|
372
|
+
ConnectableMock1.should_receive(:table_exists?).and_return(false)
|
|
373
|
+
ConnectableMock1.has_attr(:unknown_column).should == false
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it "should return nil if can't connection cause of Exception" do
|
|
377
|
+
ConnectableMock1.should_receive(:connected?).twice.and_return(false)
|
|
378
|
+
ConnectableMock1.should_receive(:connection).and_raise(IOError.new("can't connect to DB"))
|
|
379
|
+
ConnectableMock1.has_attr(:unknown_column).should == nil
|
|
306
380
|
end
|
|
307
381
|
end
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
382
|
+
|
|
383
|
+
describe "enum_for" do
|
|
384
|
+
class EnumMock10 < EnumBase
|
|
385
|
+
selectable_attr :enum1, :default => 2 do
|
|
386
|
+
entry 1, :entry1, "エントリ1"
|
|
387
|
+
entry 2, :entry2, "エントリ2"
|
|
388
|
+
entry 3, :entry3, "エントリ3"
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it "return constant by Symbol access" do
|
|
393
|
+
enum1 = EnumMock10.enum_for(:enum1)
|
|
394
|
+
enum1.class.should == SelectableAttr::Enum
|
|
314
395
|
end
|
|
396
|
+
|
|
397
|
+
it "return constant by String access" do
|
|
398
|
+
enum1 = EnumMock10.enum_for('enum1')
|
|
399
|
+
enum1.class.should == SelectableAttr::Enum
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it "return nil for unexist attr" do
|
|
403
|
+
enum1 = EnumMock10.enum_for('unexist_attr')
|
|
404
|
+
enum1.should == nil
|
|
405
|
+
end
|
|
406
|
+
|
|
315
407
|
end
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
408
|
+
|
|
409
|
+
describe "define_accessor" do
|
|
410
|
+
class DefiningMock1 < EnumBase
|
|
411
|
+
class << self
|
|
412
|
+
def attr_accessor_with_default(*args); end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
323
415
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
416
|
+
it "should call attr_accessor_with_default when both of attr_accessor and default are given" do
|
|
417
|
+
DefiningMock1.should_receive(:attr_accessor_with_default).with(:enum1, 1)
|
|
418
|
+
DefiningMock1.define_accessor(:attr => :enum1, :attr_accessor => true, :default => 1)
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
it "should call attr_accessor_with_default when default are given but attr_accessor is not TRUE" do
|
|
422
|
+
$stderr.should_receive(:puts).with("WARNING! :default option ignored for enum1")
|
|
423
|
+
DefiningMock1.define_accessor(:attr => :enum1, :attr_accessor => false, :default => 1)
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
|
|
329
427
|
end
|
|
330
428
|
|
|
429
|
+
|
|
331
430
|
end
|
|
@@ -114,4 +114,16 @@ describe SelectableAttr::Enum do
|
|
|
114
114
|
]
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
+
describe "find" do
|
|
118
|
+
it "with options" do
|
|
119
|
+
InetAccess.find(:protocol => 'http://').should == InetAccess[2]
|
|
120
|
+
InetAccess.find(:protocol => 'svn+ssh://').should == SelectableAttr::Enum::Entry::NULL
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "with block" do
|
|
124
|
+
InetAccess.find{|entry| entry.key.to_s =~ /tp/}.should == InetAccess[3]
|
|
125
|
+
InetAccess.find{|entry| entry.key.to_s =~ /XXXXXX/}.should == SelectableAttr::Enum::Entry::NULL
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
117
129
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require 'yaml_waml'
|
|
3
|
+
|
|
4
|
+
namespace :i18n do
|
|
5
|
+
namespace :selectable_attr do
|
|
6
|
+
task :load_all_models => :environment do
|
|
7
|
+
Dir.glob(File.join(RAILS_ROOT, 'app', 'models', '**', '*.rb')) do |file_name|
|
|
8
|
+
require file_name
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
desc "Export i18n resources for selectable_attr entries"
|
|
13
|
+
task :export => :"i18n:selectable_attr:load_all_models" do
|
|
14
|
+
obj = {I18n.locale => SelectableAttr::Enum.i18n_export}
|
|
15
|
+
puts YAML.dump(obj)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/uninstall.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Uninstall hook code here
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: akm-selectable_attr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Takeshi Akima
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-
|
|
12
|
+
date: 2009-08-17 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|
|
@@ -19,23 +19,31 @@ executables: []
|
|
|
19
19
|
|
|
20
20
|
extensions: []
|
|
21
21
|
|
|
22
|
-
extra_rdoc_files:
|
|
23
|
-
|
|
22
|
+
extra_rdoc_files:
|
|
23
|
+
- README
|
|
24
24
|
files:
|
|
25
|
+
- .gitignore
|
|
26
|
+
- MIT-LICENSE
|
|
27
|
+
- README
|
|
28
|
+
- Rakefile
|
|
25
29
|
- VERSION.yml
|
|
26
|
-
-
|
|
30
|
+
- init.rb
|
|
31
|
+
- install.rb
|
|
32
|
+
- lib/selectable_attr.rb
|
|
27
33
|
- lib/selectable_attr/base.rb
|
|
28
34
|
- lib/selectable_attr/enum.rb
|
|
29
35
|
- lib/selectable_attr/version.rb
|
|
30
|
-
-
|
|
36
|
+
- selectable_attr.gemspec
|
|
31
37
|
- spec/selectable_attr_base_alias_spec.rb
|
|
32
38
|
- spec/selectable_attr_enum_spec.rb
|
|
33
39
|
- spec/spec_helper.rb
|
|
34
|
-
|
|
40
|
+
- tasks/selectable_attr_tasks.rake
|
|
41
|
+
- uninstall.rb
|
|
42
|
+
has_rdoc: false
|
|
35
43
|
homepage: http://github.com/akm/selectable_attr/
|
|
44
|
+
licenses:
|
|
36
45
|
post_install_message:
|
|
37
46
|
rdoc_options:
|
|
38
|
-
- --inline-source
|
|
39
47
|
- --charset=UTF-8
|
|
40
48
|
require_paths:
|
|
41
49
|
- lib
|
|
@@ -54,9 +62,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
54
62
|
requirements: []
|
|
55
63
|
|
|
56
64
|
rubyforge_project:
|
|
57
|
-
rubygems_version: 1.
|
|
65
|
+
rubygems_version: 1.3.5
|
|
58
66
|
signing_key:
|
|
59
|
-
specification_version:
|
|
67
|
+
specification_version: 3
|
|
60
68
|
summary: selectable_attr generates extra methods dynamically
|
|
61
|
-
test_files:
|
|
62
|
-
|
|
69
|
+
test_files:
|
|
70
|
+
- spec/selectable_attr_base_alias_spec.rb
|
|
71
|
+
- spec/selectable_attr_enum_spec.rb
|
|
72
|
+
- spec/spec_helper.rb
|