akm-selectable_attr 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +4 -0
- data/lib/selectable_attr/base.rb +304 -0
- data/lib/selectable_attr/enum.rb +190 -0
- data/lib/selectable_attr/version.rb +3 -0
- data/lib/selectable_attr.rb +6 -0
- data/spec/selectable_attr_base_alias_spec.rb +331 -0
- data/spec/selectable_attr_enum_spec.rb +117 -0
- data/spec/spec_helper.rb +11 -0
- metadata +62 -0
data/VERSION.yml
ADDED
@@ -0,0 +1,304 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SelectableAttr
|
3
|
+
module Base
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
ENUM_ARRAY_METHODS = {
|
9
|
+
:none => {
|
10
|
+
:to_hash_array => Proc.new do |enum, attr_value|
|
11
|
+
value = (attr_value || []).map(&:to_s)
|
12
|
+
enum.to_hash_array do |hash|
|
13
|
+
hash[:select] = value.include?(hash[:id].to_s)
|
14
|
+
end
|
15
|
+
end,
|
16
|
+
|
17
|
+
:to_attr_value => Proc.new do |enum, hash_array|
|
18
|
+
hash_array.select{|hash| hash[:select]}.map{|hash| hash[:id]}
|
19
|
+
end
|
20
|
+
},
|
21
|
+
|
22
|
+
:comma_string => {
|
23
|
+
:to_hash_array => Proc.new do |enum, attr_value|
|
24
|
+
values = attr_value.is_a?(Array) ? attr_value.map{|v|v.to_s} :
|
25
|
+
(attr_value || '').split(',')
|
26
|
+
enum.to_hash_array do |hash|
|
27
|
+
hash[:select] = values.include?(hash[:id].to_s)
|
28
|
+
end
|
29
|
+
end,
|
30
|
+
|
31
|
+
:to_attr_value => Proc.new do |enum, hash_array|
|
32
|
+
hash_array.select{|hash| hash[:select]}.map{|hash| hash[:id]}.join(',')
|
33
|
+
end
|
34
|
+
},
|
35
|
+
|
36
|
+
|
37
|
+
:binary_string => {
|
38
|
+
:to_hash_array => Proc.new do |enum, attr_value|
|
39
|
+
value = attr_value || ''
|
40
|
+
idx = 0
|
41
|
+
enum.to_hash_array do |hash|
|
42
|
+
hash[:select] = (value[idx, 1] == '1')
|
43
|
+
idx += 1
|
44
|
+
end
|
45
|
+
end,
|
46
|
+
|
47
|
+
:to_attr_value => Proc.new do |enum, hash_array|
|
48
|
+
result = ''
|
49
|
+
hash_map = hash_array.inject({}){|dest, hash| dest[hash[:id]] = hash; dest}
|
50
|
+
enum.each do |entry|
|
51
|
+
hash = hash_map[entry.id]
|
52
|
+
result << (hash[:select] ? '1' : '0')
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
module ClassMethods
|
60
|
+
def single_selectable_attrs
|
61
|
+
@single_selectable_attrs_hash ||= {};
|
62
|
+
@single_selectable_attrs_hash[self] ||= []
|
63
|
+
end
|
64
|
+
|
65
|
+
def multi_selectable_attrs
|
66
|
+
@multi_selectable_attrs_hash ||= {};
|
67
|
+
@multi_selectable_attrs_hash[self] ||= []
|
68
|
+
end
|
69
|
+
|
70
|
+
def selectable_attr_type_for(attr)
|
71
|
+
single_selectable_attrs.include?(attr) ? :single :
|
72
|
+
multi_selectable_attrs.include?(attr) ? :multi : nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def enum(*args, &block)
|
76
|
+
process_definition(block, *args) do |enum, context|
|
77
|
+
self.single_selectable_attrs << context[:attr].to_s
|
78
|
+
define_enum_class_methods(context)
|
79
|
+
define_enum_instance_methods(context)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
alias_method :single_selectable_attr, :enum
|
83
|
+
alias_method :selectable_attr, :enum
|
84
|
+
|
85
|
+
|
86
|
+
def enum_array(*args, &block)
|
87
|
+
base_options = args.last.is_a?(Hash) ? args.pop : {}
|
88
|
+
args << base_options # .update({:attr_accessor => false})
|
89
|
+
process_definition(block, *args) do |enum, context|
|
90
|
+
self.multi_selectable_attrs << context[:attr].to_s
|
91
|
+
define_enum_class_methods(context)
|
92
|
+
define_enum_array_instance_methods(context)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
alias_method :multi_selectable_attr, :enum_array
|
96
|
+
|
97
|
+
def process_definition(block, *args)
|
98
|
+
base_options = args.last.is_a?(Hash) ? args.pop : {}
|
99
|
+
enum = base_options[:enum] || create_enum(&block)
|
100
|
+
args.each do |attr|
|
101
|
+
context = {
|
102
|
+
:enum => enum,
|
103
|
+
:attr_accessor => !has_attr(attr),
|
104
|
+
:attr => attr,
|
105
|
+
:base_name => enum_base_name(attr)
|
106
|
+
}.update(base_options)
|
107
|
+
define_enum(context)
|
108
|
+
define_accessor(context)
|
109
|
+
yield(enum, context)
|
110
|
+
unless enum.i18n_scope
|
111
|
+
paths = [:selectable_attrs] + self.name.to_s.split('::').map{|s| s.to_sym}
|
112
|
+
paths << attr.to_sym
|
113
|
+
enum.i18n_scope(*paths)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
enum
|
117
|
+
end
|
118
|
+
|
119
|
+
def has_attr(attr)
|
120
|
+
return true if self.method_defined?(attr)
|
121
|
+
return false unless self.respond_to?(:columns)
|
122
|
+
if self.respond_to?(:connection) and self.respond_to?(:connected?)
|
123
|
+
begin
|
124
|
+
self.connection unless self.connected?
|
125
|
+
rescue Exception
|
126
|
+
return nil if !self.connected?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
(self.columns || []).any?{|col|col.name.to_s == attr.to_s}
|
130
|
+
end
|
131
|
+
|
132
|
+
def attr_enumeable_base(*args, &block)
|
133
|
+
@base_name_processor = block
|
134
|
+
end
|
135
|
+
|
136
|
+
def enum_base_name(attr)
|
137
|
+
if @base_name_processor
|
138
|
+
@base_name_processor.call(attr).to_s
|
139
|
+
else
|
140
|
+
attr.to_s.gsub(selectable_attr_name_pattern, '')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
DEFAULT_SELECTABLE_ATTR_NAME_PATTERN = /(_cd$|_code$|_cds$|_codes$)/
|
145
|
+
|
146
|
+
def selectable_attr_name_pattern
|
147
|
+
@selectable_attr_name_pattern ||= DEFAULT_SELECTABLE_ATTR_NAME_PATTERN
|
148
|
+
end
|
149
|
+
alias_method :enum_name_pattern, :selectable_attr_name_pattern
|
150
|
+
|
151
|
+
def selectable_attr_name_pattern=(value)
|
152
|
+
@selectable_attr_name_pattern = value
|
153
|
+
end
|
154
|
+
alias_method :enum_name_pattern=, :selectable_attr_name_pattern=
|
155
|
+
|
156
|
+
def create_enum(&block)
|
157
|
+
result = Enum.new
|
158
|
+
result.instance_eval(&block)
|
159
|
+
result
|
160
|
+
end
|
161
|
+
|
162
|
+
def define_enum(context)
|
163
|
+
base_name = context[:base_name]
|
164
|
+
const_name = "#{base_name.upcase}_ENUM"
|
165
|
+
const_set(const_name, context[:enum]) unless const_defined?(const_name)
|
166
|
+
end
|
167
|
+
|
168
|
+
def enum_for(attr)
|
169
|
+
base_name = enum_base_name(attr)
|
170
|
+
const_get("#{base_name.upcase}_ENUM")
|
171
|
+
end
|
172
|
+
|
173
|
+
def define_accessor(context)
|
174
|
+
attr = context[:attr]
|
175
|
+
return unless (instance_methods & [attr, "#{attr}="]).empty?
|
176
|
+
if context[:attr_accessor]
|
177
|
+
if context[:default]
|
178
|
+
if respond_to?(:attr_accessor_with_default)
|
179
|
+
attr_accessor_with_default(attr, context[:default])
|
180
|
+
else
|
181
|
+
instance_var_name = "@#{attr}"
|
182
|
+
attr_writer(attr)
|
183
|
+
define_method(attr) do
|
184
|
+
value = instance_variable_get(instance_var_name)
|
185
|
+
instance_variable_set(instance_var_name, value = context[:default]) unless value
|
186
|
+
value
|
187
|
+
end
|
188
|
+
end
|
189
|
+
else
|
190
|
+
attr_accessor(attr)
|
191
|
+
end
|
192
|
+
else
|
193
|
+
if context[:default]
|
194
|
+
$stderr.puts "WARNING! :default option ignored for #{attr}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def define_enum_class_methods(context)
|
200
|
+
base_name = context[:base_name]
|
201
|
+
enum = context[:enum]
|
202
|
+
mod = Module.new
|
203
|
+
mod.module_eval do
|
204
|
+
define_method("#{base_name}_enum"){enum}
|
205
|
+
define_method("#{base_name}_hash_array"){enum.to_hash_array}
|
206
|
+
define_method("#{base_name}_entries"){enum.entries}
|
207
|
+
define_method("#{base_name}_options"){|*ids_or_keys|enum.options(*ids_or_keys)}
|
208
|
+
define_method("#{base_name}_ids"){|*ids_or_keys| enum.ids(*ids_or_keys)}
|
209
|
+
define_method("#{base_name}_keys"){|*ids_or_keys|enum.keys(*ids_or_keys)}
|
210
|
+
define_method("#{base_name}_names"){|*ids_or_keys|enum.names(*ids_or_keys)}
|
211
|
+
define_method("#{base_name}_key_by_id"){|id|enum.key_by_id(id)}
|
212
|
+
define_method("#{base_name}_id_by_key"){|key|enum.id_by_key(key)}
|
213
|
+
define_method("#{base_name}_name_by_id"){|id|enum.name_by_id(id)}
|
214
|
+
define_method("#{base_name}_name_by_key"){|key|enum.name_by_key(key)}
|
215
|
+
define_method("#{base_name}_entry_by_id"){|id|enum.entry_by_id(id)}
|
216
|
+
define_method("#{base_name}_entry_by_key"){|key|enum.entry_by_key(key)}
|
217
|
+
end
|
218
|
+
if convertors = ENUM_ARRAY_METHODS[context[:convert_with] || :none]
|
219
|
+
mod.module_eval do
|
220
|
+
define_method("#{base_name}_to_hash_array", convertors[:to_hash_array])
|
221
|
+
define_method("hash_array_to_#{base_name}", convertors[:to_attr_value])
|
222
|
+
end
|
223
|
+
end
|
224
|
+
self.extend(mod)
|
225
|
+
end
|
226
|
+
|
227
|
+
def define_enum_instance_methods(context)
|
228
|
+
attr = context[:attr]
|
229
|
+
base_name = context[:base_name]
|
230
|
+
instance_methods = <<-EOS
|
231
|
+
def #{base_name}_key
|
232
|
+
self.class.#{base_name}_key_by_id(#{attr})
|
233
|
+
end
|
234
|
+
def #{base_name}_key=(key)
|
235
|
+
self.#{attr} = self.class.#{base_name}_id_by_key(key)
|
236
|
+
end
|
237
|
+
def #{base_name}_name
|
238
|
+
self.class.#{base_name}_name_by_id(#{attr})
|
239
|
+
end
|
240
|
+
def #{base_name}_entry
|
241
|
+
self.class.#{base_name}_entry_by_id(#{attr})
|
242
|
+
end
|
243
|
+
def #{base_name}_entry
|
244
|
+
self.class.#{base_name}_entry_by_id(#{attr})
|
245
|
+
end
|
246
|
+
EOS
|
247
|
+
self.module_eval(instance_methods)
|
248
|
+
end
|
249
|
+
|
250
|
+
def define_enum_array_instance_methods(context)
|
251
|
+
attr = context[:attr]
|
252
|
+
base_name = context[:base_name]
|
253
|
+
# ActiveRecord::Baseから継承している場合は、基本カラムに対応するメソッドはない
|
254
|
+
self.module_eval(<<-"EOS")
|
255
|
+
def #{base_name}_ids
|
256
|
+
#{base_name}_hash_array_selected.map{|hash|hash[:id]}
|
257
|
+
end
|
258
|
+
def #{base_name}_ids=(ids)
|
259
|
+
ids = ids.split(',') if ids.is_a?(String)
|
260
|
+
ids = ids ? ids.map(&:to_s) : []
|
261
|
+
update_#{base_name}_hash_array{|hash|ids.include?(hash[:id].to_s)}
|
262
|
+
end
|
263
|
+
EOS
|
264
|
+
self.module_eval(<<-"EOS")
|
265
|
+
def #{base_name}_hash_array
|
266
|
+
self.class.#{base_name}_to_hash_array(self.class.#{base_name}_enum, #{attr})
|
267
|
+
end
|
268
|
+
def #{base_name}_hash_array=(hash_array)
|
269
|
+
self.#{attr} = self.class.hash_array_to_#{base_name}(self.class.#{base_name}_enum, hash_array)
|
270
|
+
end
|
271
|
+
def #{base_name}_hash_array_selected
|
272
|
+
#{base_name}_hash_array.select{|hash|!!hash[:select]}
|
273
|
+
end
|
274
|
+
def update_#{base_name}_hash_array(&block)
|
275
|
+
hash_array = #{base_name}_hash_array.map do |hash|
|
276
|
+
hash.merge(:select => yield(hash))
|
277
|
+
end
|
278
|
+
self.#{base_name}_hash_array = hash_array
|
279
|
+
end
|
280
|
+
def #{base_name}_keys
|
281
|
+
#{base_name}_hash_array_selected.map{|hash|hash[:key]}
|
282
|
+
end
|
283
|
+
def #{base_name}_keys=(keys)
|
284
|
+
update_#{base_name}_hash_array{|hash|keys.include?(hash[:key])}
|
285
|
+
end
|
286
|
+
def #{base_name}_selection
|
287
|
+
#{base_name}_hash_array.map{|hash|!!hash[:select]}
|
288
|
+
end
|
289
|
+
def #{base_name}_selection=(selection)
|
290
|
+
idx = -1
|
291
|
+
update_#{base_name}_hash_array{|hash| idx += 1; !!selection[idx]}
|
292
|
+
end
|
293
|
+
def #{base_name}_names
|
294
|
+
#{base_name}_hash_array_selected.map{|hash|hash[:name]}
|
295
|
+
end
|
296
|
+
def #{base_name}_entries
|
297
|
+
ids = #{base_name}_ids
|
298
|
+
self.class.#{base_name}_enum.select{|entry|ids.include?(entry.id)}
|
299
|
+
end
|
300
|
+
EOS
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
module SelectableAttr
|
2
|
+
|
3
|
+
class Enum
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def instances
|
8
|
+
@@instances ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
if defined?(I18n)
|
12
|
+
def i18n_export
|
13
|
+
result = {}
|
14
|
+
instances.each do |instance|
|
15
|
+
unless instance.i18n_scope
|
16
|
+
# puts "no i18n_scope of #{instance.inspect}"
|
17
|
+
next
|
18
|
+
end
|
19
|
+
paths = instance.i18n_scope.dup
|
20
|
+
current = result
|
21
|
+
paths.each do |path|
|
22
|
+
current = current[path] ||= {}
|
23
|
+
end
|
24
|
+
instance.entries.each do |entry|
|
25
|
+
current[entry.key] = entry.name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(&block)
|
34
|
+
@entries = []
|
35
|
+
instance_eval(&block) if block_given?
|
36
|
+
SelectableAttr::Enum.instances << self if defined?(I18n)
|
37
|
+
end
|
38
|
+
|
39
|
+
def entries
|
40
|
+
@entries
|
41
|
+
end
|
42
|
+
|
43
|
+
def each(&block)
|
44
|
+
entries.each(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def define(id, key, name, options = nil, &block)
|
48
|
+
entry = Entry.new(self, id, key, name, options, &block)
|
49
|
+
entry.instance_variable_set(:@defined_in_code, true)
|
50
|
+
@entries << entry
|
51
|
+
end
|
52
|
+
alias_method :entry, :define
|
53
|
+
|
54
|
+
def i18n_scope(*path)
|
55
|
+
@i18n_scope = path unless path.empty?
|
56
|
+
@i18n_scope
|
57
|
+
end
|
58
|
+
|
59
|
+
def match_entry(entry, value, *attrs)
|
60
|
+
attrs.any?{|attr| entry[attr].to_s == value.to_s}
|
61
|
+
end
|
62
|
+
|
63
|
+
def entry_by(value, *attrs)
|
64
|
+
entries.detect{|entry| match_entry(entry, value, *attrs)} || Entry::NULL
|
65
|
+
end
|
66
|
+
|
67
|
+
def entry_by_id(id)
|
68
|
+
entry_by(id, :id)
|
69
|
+
end
|
70
|
+
|
71
|
+
def entry_by_key(key)
|
72
|
+
entry_by(key, :key)
|
73
|
+
end
|
74
|
+
|
75
|
+
def entry_by_id_or_key(id_or_key)
|
76
|
+
entry_by(id_or_key, :id, :key)
|
77
|
+
end
|
78
|
+
|
79
|
+
def entry_by_hash(attrs)
|
80
|
+
entries.detect{|entry| attrs.all?{|(attr, value)| entry[attr].to_s == value.to_s }} || Entry::NULL
|
81
|
+
end
|
82
|
+
|
83
|
+
def [](arg)
|
84
|
+
arg.is_a?(Hash) ? entry_by_hash(arg) : entry_by_id_or_key(arg)
|
85
|
+
end
|
86
|
+
|
87
|
+
def values(*args)
|
88
|
+
args = args.empty? ? [:name, :id] : args
|
89
|
+
result = entries.collect{|entry| args.collect{|arg| entry.send(arg) }}
|
90
|
+
(args.length == 1) ? result.flatten : result
|
91
|
+
end
|
92
|
+
|
93
|
+
def map_attrs(attrs, *ids_or_keys)
|
94
|
+
if attrs.is_a?(Array)
|
95
|
+
ids_or_keys.empty? ?
|
96
|
+
entries.map{|entry| attrs.map{|attr|entry.send(attr)}} :
|
97
|
+
ids_or_keys.map do |id_or_key|
|
98
|
+
entry = entry_by_id_or_key(id_or_key)
|
99
|
+
attrs.map{|attr|entry.send(attr)}
|
100
|
+
end
|
101
|
+
else
|
102
|
+
attr = attrs
|
103
|
+
ids_or_keys.empty? ?
|
104
|
+
entries.map(&attr.to_sym) :
|
105
|
+
ids_or_keys.map{|id_or_key|entry_by_id_or_key(id_or_key).send(attr)}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def ids(*ids_or_keys); map_attrs(:id, *ids_or_keys); end
|
110
|
+
def keys(*ids_or_keys); map_attrs(:key, *ids_or_keys); end
|
111
|
+
def names(*ids_or_keys); map_attrs(:name, *ids_or_keys); end
|
112
|
+
def options(*ids_or_keys); map_attrs([:name, :id], *ids_or_keys); end
|
113
|
+
|
114
|
+
def key_by_id(id); entry_by_id(id).key; end
|
115
|
+
def id_by_key(key); entry_by_key(key).id; end
|
116
|
+
def name_by_id(id); entry_by_id(id).name; end
|
117
|
+
def name_by_key(key); entry_by_key(key).name; end
|
118
|
+
|
119
|
+
def find(options = nil, &block)
|
120
|
+
entries.detect{|entry|
|
121
|
+
block_given? ? yield(entry) : entry.match?(options)
|
122
|
+
} || Entry::NULL
|
123
|
+
end
|
124
|
+
|
125
|
+
def to_hash_array
|
126
|
+
entries.map do |entry|
|
127
|
+
result = entry.to_hash
|
128
|
+
yield(result) if defined? yield
|
129
|
+
result
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def length
|
134
|
+
entries.length
|
135
|
+
end
|
136
|
+
alias_method :size, :length
|
137
|
+
|
138
|
+
class Entry
|
139
|
+
BASE_ATTRS = [:id, :key, :name]
|
140
|
+
attr_reader :id, :key
|
141
|
+
attr_reader :defined_in_code
|
142
|
+
def initialize(enum, id, key, name, options = nil, &block)
|
143
|
+
@enum = enum
|
144
|
+
@id = id
|
145
|
+
@key = key
|
146
|
+
@name = name
|
147
|
+
@options = options
|
148
|
+
self.instance_eval(&block) if block
|
149
|
+
end
|
150
|
+
|
151
|
+
if defined?(I18n)
|
152
|
+
def name
|
153
|
+
I18n.locale.nil? ? @name :
|
154
|
+
@enum.i18n_scope.blank? ? @name :
|
155
|
+
I18n.translate(key, :scope => @enum.i18n_scope, :default => @name)
|
156
|
+
end
|
157
|
+
else
|
158
|
+
attr_reader :name
|
159
|
+
end
|
160
|
+
|
161
|
+
def [](option_key)
|
162
|
+
BASE_ATTRS.include?(option_key) ? send(option_key) :
|
163
|
+
@options ? @options[option_key] : nil
|
164
|
+
end
|
165
|
+
|
166
|
+
def match?(options)
|
167
|
+
@options === options
|
168
|
+
end
|
169
|
+
|
170
|
+
def null?
|
171
|
+
false
|
172
|
+
end
|
173
|
+
|
174
|
+
def null_object?
|
175
|
+
self.null?
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_hash
|
179
|
+
(@options || {}).merge(:id => @id, :key => @key, :name => @name)
|
180
|
+
end
|
181
|
+
|
182
|
+
NULL = new(nil, nil, nil, nil) do
|
183
|
+
def null?; true; end
|
184
|
+
def name; nil; end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
describe SelectableAttr do
|
5
|
+
|
6
|
+
def assert_enum_class_methods(klass, attr = :enum1)
|
7
|
+
klass.send("#{attr}_enum").length.should == 3
|
8
|
+
expected_hash_array = [
|
9
|
+
{:id => 1, :key => :entry1, :name => "エントリ1"},
|
10
|
+
{:id => 2, :key => :entry2, :name => "エントリ2"},
|
11
|
+
{:id => 3, :key => :entry3, :name => "エントリ3"}
|
12
|
+
]
|
13
|
+
klass.send("#{attr}_hash_array").should == expected_hash_array
|
14
|
+
klass.send("#{attr}_enum").to_hash_array.should == expected_hash_array
|
15
|
+
klass.send("#{attr}_entries").
|
16
|
+
map{|entry| {:id => entry.id, :key => entry.key, :name => entry.name} }.
|
17
|
+
should == expected_hash_array
|
18
|
+
|
19
|
+
klass.send("#{attr}_ids").should == [1,2,3]
|
20
|
+
klass.send("#{attr}_ids", :entry2, :entry3).should == [2,3]
|
21
|
+
klass.send("#{attr}_keys").should == [:entry1, :entry2, :entry3]
|
22
|
+
klass.send("#{attr}_keys", 1,3).should == [:entry1, :entry3]
|
23
|
+
klass.send("#{attr}_names").should == ["エントリ1", "エントリ2", "エントリ3"]
|
24
|
+
klass.send("#{attr}_names", 1,2).should == ["エントリ1", "エントリ2"]
|
25
|
+
klass.send("#{attr}_names", :entry1, :entry2).should == ["エントリ1", "エントリ2"]
|
26
|
+
klass.send("#{attr}_options").should == [['エントリ1', 1], ['エントリ2', 2], ['エントリ3', 3]]
|
27
|
+
klass.send("#{attr}_options", :entry2, :entry3).should == [['エントリ2', 2], ['エントリ3', 3]]
|
28
|
+
klass.send("#{attr}_options", 1,2).should == [['エントリ1', 1], ['エントリ2', 2]]
|
29
|
+
|
30
|
+
klass.send("#{attr}_id_by_key", nil).should be_nil
|
31
|
+
klass.send("#{attr}_id_by_key", :entry1).should == 1
|
32
|
+
klass.send("#{attr}_id_by_key", :entry2).should == 2
|
33
|
+
klass.send("#{attr}_id_by_key", :entry3).should == 3
|
34
|
+
klass.send("#{attr}_name_by_key", nil).should be_nil
|
35
|
+
klass.send("#{attr}_name_by_key", :entry1).should == "エントリ1"
|
36
|
+
klass.send("#{attr}_name_by_key", :entry2).should == "エントリ2"
|
37
|
+
klass.send("#{attr}_name_by_key", :entry3).should == "エントリ3"
|
38
|
+
|
39
|
+
klass.send("#{attr}_key_by_id", nil).should be_nil
|
40
|
+
klass.send("#{attr}_key_by_id", 1).should == :entry1
|
41
|
+
klass.send("#{attr}_key_by_id", 2).should == :entry2
|
42
|
+
klass.send("#{attr}_key_by_id", 3).should == :entry3
|
43
|
+
klass.send("#{attr}_name_by_id", nil).should be_nil
|
44
|
+
klass.send("#{attr}_name_by_id", 1).should == "エントリ1"
|
45
|
+
klass.send("#{attr}_name_by_id", 2).should == "エントリ2"
|
46
|
+
klass.send("#{attr}_name_by_id", 3).should == "エントリ3"
|
47
|
+
end
|
48
|
+
|
49
|
+
def assert_single_enum_instance_methods(obj, attr = :enum1)
|
50
|
+
obj.send("#{attr}=", 1)
|
51
|
+
obj.send(attr).should == 1
|
52
|
+
obj.enum1_key.should == :entry1
|
53
|
+
obj.enum1_name.should == "エントリ1"
|
54
|
+
obj.enum1_entry.to_hash.should == {:id => 1, :key => :entry1, :name => "エントリ1"}
|
55
|
+
|
56
|
+
obj.enum1_key = :entry2
|
57
|
+
obj.send(attr).should == 2
|
58
|
+
obj.enum1_key.should == :entry2
|
59
|
+
obj.enum1_name.should == "エントリ2"
|
60
|
+
obj.enum1_entry.to_hash.should == {:id => 2, :key => :entry2, :name => "エントリ2"}
|
61
|
+
|
62
|
+
obj.send("#{attr}=", 3)
|
63
|
+
obj.send(attr).should == 3
|
64
|
+
obj.enum1_key.should == :entry3
|
65
|
+
obj.enum1_name.should == "エントリ3"
|
66
|
+
obj.enum1_entry.to_hash.should == {:id => 3, :key => :entry3, :name => "エントリ3"}
|
67
|
+
end
|
68
|
+
|
69
|
+
class EnumBase
|
70
|
+
include ::SelectableAttr::Base
|
71
|
+
end
|
72
|
+
|
73
|
+
class EnumMock1 < EnumBase
|
74
|
+
selectable_attr :enum1, :default => 2 do
|
75
|
+
entry 1, :entry1, "エントリ1"
|
76
|
+
entry 2, :entry2, "エントリ2"
|
77
|
+
entry 3, :entry3, "エントリ3"
|
78
|
+
end
|
79
|
+
end
|
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"
|
86
|
+
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
|
+
|
102
|
+
class EnumMock2 < EnumBase
|
103
|
+
attr_enumeable_base do |attr|
|
104
|
+
attr.to_s.gsub(/(.*)_code(.*)$/){"#{$1}#{$2}"}
|
105
|
+
end
|
106
|
+
|
107
|
+
selectable_attr :enum_code1 do
|
108
|
+
entry 1, :entry1, "エントリ1"
|
109
|
+
entry 2, :entry2, "エントリ2"
|
110
|
+
entry 3, :entry3, "エントリ3"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class EnumMock2WithEnum < EnumBase
|
115
|
+
attr_enumeable_base do |attr|
|
116
|
+
attr.to_s.gsub(/(.*)_code(.*)$/){"#{$1}#{$2}"}
|
117
|
+
end
|
118
|
+
|
119
|
+
enum :enum_code1 do
|
120
|
+
entry 1, :entry1, "エントリ1"
|
121
|
+
entry 2, :entry2, "エントリ2"
|
122
|
+
entry 3, :entry3, "エントリ3"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it "test_selectable_attr2" do
|
127
|
+
assert_enum_class_methods(EnumMock2)
|
128
|
+
assert_single_enum_instance_methods(EnumMock2.new, :enum_code1)
|
129
|
+
assert_enum_class_methods(EnumMock2WithEnum)
|
130
|
+
assert_single_enum_instance_methods(EnumMock2WithEnum.new, :enum_code1)
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
def assert_multi_enum_instance_methods(obj, patterns)
|
136
|
+
obj.enum_array1_hash_array.should == [
|
137
|
+
{:id => 1, :key => :entry1, :name => "エントリ1", :select => false},
|
138
|
+
{:id => 2, :key => :entry2, :name => "エントリ2", :select => false},
|
139
|
+
{:id => 3, :key => :entry3, :name => "エントリ3", :select => false}
|
140
|
+
]
|
141
|
+
obj.enum_array1_selection.should == [false, false, false]
|
142
|
+
obj.enum_array1.should be_nil
|
143
|
+
obj.enum_array1_entries.should == []
|
144
|
+
obj.enum_array1_keys.should == []
|
145
|
+
obj.enum_array1_names.should == []
|
146
|
+
|
147
|
+
obj.enum_array1 = patterns[0]
|
148
|
+
obj.enum_array1.should == patterns[0]
|
149
|
+
obj.enum_array1_hash_array.should == [
|
150
|
+
{:id => 1, :key => :entry1, :name => "エントリ1", :select => false},
|
151
|
+
{:id => 2, :key => :entry2, :name => "エントリ2", :select => false},
|
152
|
+
{:id => 3, :key => :entry3, :name => "エントリ3", :select => false}
|
153
|
+
]
|
154
|
+
obj.enum_array1_selection.should == [false, false, false]
|
155
|
+
obj.enum_array1_entries.should == []
|
156
|
+
obj.enum_array1_keys.should == []
|
157
|
+
obj.enum_array1_names.should == []
|
158
|
+
|
159
|
+
obj.enum_array1 = patterns[1]
|
160
|
+
obj.enum_array1.should == patterns[1]
|
161
|
+
obj.enum_array1_hash_array.should == [
|
162
|
+
{:id => 1, :key => :entry1, :name => "エントリ1", :select => false},
|
163
|
+
{:id => 2, :key => :entry2, :name => "エントリ2", :select => false},
|
164
|
+
{:id => 3, :key => :entry3, :name => "エントリ3", :select => true}
|
165
|
+
]
|
166
|
+
obj.enum_array1_selection.should == [false, false, true]
|
167
|
+
obj.enum_array1_entries.map(&:id).should == [3]
|
168
|
+
obj.enum_array1_keys.should == [:entry3]
|
169
|
+
obj.enum_array1_names.should == ['エントリ3']
|
170
|
+
|
171
|
+
obj.enum_array1 = patterns[3]
|
172
|
+
obj.enum_array1.should == patterns[3]
|
173
|
+
obj.enum_array1_hash_array.should == [
|
174
|
+
{:id => 1, :key => :entry1, :name => "エントリ1", :select => false},
|
175
|
+
{:id => 2, :key => :entry2, :name => "エントリ2", :select => true},
|
176
|
+
{:id => 3, :key => :entry3, :name => "エントリ3", :select => true}
|
177
|
+
]
|
178
|
+
obj.enum_array1_selection.should == [false, true, true]
|
179
|
+
obj.enum_array1_entries.map(&:id).should == [2, 3]
|
180
|
+
obj.enum_array1_keys.should == [:entry2, :entry3]
|
181
|
+
obj.enum_array1_names.should == ['エントリ2', 'エントリ3']
|
182
|
+
|
183
|
+
obj.enum_array1 = patterns[7]
|
184
|
+
obj.enum_array1.should == patterns[7]
|
185
|
+
obj.enum_array1_hash_array.should == [
|
186
|
+
{:id => 1, :key => :entry1, :name => "エントリ1", :select => true},
|
187
|
+
{:id => 2, :key => :entry2, :name => "エントリ2", :select => true},
|
188
|
+
{:id => 3, :key => :entry3, :name => "エントリ3", :select => true}
|
189
|
+
]
|
190
|
+
obj.enum_array1_selection.should == [true, true, true]
|
191
|
+
obj.enum_array1_ids.should == [1, 2, 3]
|
192
|
+
obj.enum_array1_entries.map(&:id).should == [1, 2, 3]
|
193
|
+
obj.enum_array1_keys.should == [:entry1, :entry2, :entry3]
|
194
|
+
obj.enum_array1_names.should == ['エントリ1', 'エントリ2', 'エントリ3']
|
195
|
+
|
196
|
+
obj.enum_array1_ids = [1,3]; obj.enum_array1.should == patterns[5]
|
197
|
+
obj.enum_array1_ids = [1,2]; obj.enum_array1.should == patterns[6]
|
198
|
+
obj.enum_array1_ids = [2]; obj.enum_array1.should == patterns[2]
|
199
|
+
|
200
|
+
obj.enum_array1_keys = [:entry1,:entry3]; obj.enum_array1.should == patterns[5]
|
201
|
+
obj.enum_array1_keys = [:entry1,:entry2]; obj.enum_array1.should == patterns[6]
|
202
|
+
obj.enum_array1_keys = [:entry2]; obj.enum_array1.should == patterns[2]
|
203
|
+
|
204
|
+
obj.enum_array1_selection = [true, false, true]; obj.enum_array1.should == patterns[5]
|
205
|
+
obj.enum_array1_selection = [true, true, false]; obj.enum_array1.should == patterns[6]
|
206
|
+
obj.enum_array1_selection = [false, true, false]; obj.enum_array1.should == patterns[2]
|
207
|
+
|
208
|
+
obj.enum_array1_ids = "1,3"; obj.enum_array1.should == patterns[5]
|
209
|
+
obj.enum_array1_ids = "1,2"; obj.enum_array1.should == patterns[6]
|
210
|
+
obj.enum_array1_ids = "2"; obj.enum_array1.should == patterns[2]
|
211
|
+
end
|
212
|
+
|
213
|
+
class EnumMock3 < EnumBase
|
214
|
+
multi_selectable_attr :enum_array1, :convert_with => :binary_string do
|
215
|
+
entry 1, :entry1, "エントリ1"
|
216
|
+
entry 2, :entry2, "エントリ2"
|
217
|
+
entry 3, :entry3, "エントリ3"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
class EnumMock3WithEnumArray < EnumBase
|
222
|
+
enum_array :enum_array1, :convert_with => :binary_string do
|
223
|
+
entry 1, :entry1, "エントリ1"
|
224
|
+
entry 2, :entry2, "エントリ2"
|
225
|
+
entry 3, :entry3, "エントリ3"
|
226
|
+
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
|
+
|
237
|
+
class EnumMock4 < EnumBase
|
238
|
+
multi_selectable_attr :enum_array1 do
|
239
|
+
entry 1, :entry1, "エントリ1"
|
240
|
+
entry 2, :entry2, "エントリ2"
|
241
|
+
entry 3, :entry3, "エントリ3"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
class EnumMock4WithEnumArray < EnumBase
|
246
|
+
enum_array :enum_array1 do
|
247
|
+
entry 1, :entry1, "エントリ1"
|
248
|
+
entry 2, :entry2, "エントリ2"
|
249
|
+
entry 3, :entry3, "エントリ3"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
it "test_multi_selectable_attr2" do
|
254
|
+
# [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
|
255
|
+
expected =
|
256
|
+
(0..7).map do |i|
|
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
|
262
|
+
end
|
263
|
+
assert_enum_class_methods(EnumMock4, :enum_array1)
|
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
|
268
|
+
|
269
|
+
class EnumMock5 < EnumBase
|
270
|
+
multi_selectable_attr :enum_array1, :convert_with => :comma_string do
|
271
|
+
entry 1, :entry1, "エントリ1"
|
272
|
+
entry 2, :entry2, "エントリ2"
|
273
|
+
entry 3, :entry3, "エントリ3"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
class EnumMock5WithEnumArray < EnumBase
|
278
|
+
enum_array :enum_array1, :convert_with => :comma_string do
|
279
|
+
entry 1, :entry1, "エントリ1"
|
280
|
+
entry 2, :entry2, "エントリ2"
|
281
|
+
entry 3, :entry3, "エントリ3"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
it "test_multi_selectable_attr_with_comma_string" do
|
286
|
+
# ["", "3", "2", "2,3", "1", "1,3", "1,2", "1,2,3"]
|
287
|
+
expected =
|
288
|
+
(0..7).map do |i|
|
289
|
+
s = '%03b' % i
|
290
|
+
a = s.split('').map{|v| v.to_i}
|
291
|
+
ret = []
|
292
|
+
a.each_with_index{|val, pos| ret << pos + 1 if val == 1}
|
293
|
+
ret.join(',')
|
294
|
+
end
|
295
|
+
assert_enum_class_methods(EnumMock5, :enum_array1)
|
296
|
+
assert_multi_enum_instance_methods(EnumMock5.new, expected)
|
297
|
+
assert_enum_class_methods(EnumMock5WithEnumArray, :enum_array1)
|
298
|
+
assert_multi_enum_instance_methods(EnumMock5WithEnumArray.new, expected)
|
299
|
+
end
|
300
|
+
|
301
|
+
class EnumMock6 < EnumBase
|
302
|
+
# self.selectable_attr_name_pattern = /(_cd$|_code$|_cds$|_codes$)/
|
303
|
+
selectable_attr :category_id do
|
304
|
+
entry "01", :category1, "カテゴリ1"
|
305
|
+
entry "02", :category2, "カテゴリ2"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
class EnumMock7 < EnumBase
|
310
|
+
self.selectable_attr_name_pattern = /(_cd$|_id$|_cds$|_ids$)/
|
311
|
+
selectable_attr :category_id do
|
312
|
+
entry "01", :category1, "カテゴリ1"
|
313
|
+
entry "02", :category2, "カテゴリ2"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
it "test_selectable_attr_name_pattern" do
|
318
|
+
EnumMock6.selectable_attr_name_pattern.should == /(_cd$|_code$|_cds$|_codes$)/
|
319
|
+
EnumMock6.respond_to?(:category_enum).should == false
|
320
|
+
EnumMock6.respond_to?(:category_id_enum).should == true
|
321
|
+
EnumMock6.new.respond_to?(:category_key).should == false
|
322
|
+
EnumMock6.new.respond_to?(:category_id_key).should == true
|
323
|
+
|
324
|
+
EnumMock7.selectable_attr_name_pattern.should == /(_cd$|_id$|_cds$|_ids$)/
|
325
|
+
EnumMock7.respond_to?(:category_enum).should == true
|
326
|
+
EnumMock7.respond_to?(:category_id_enum).should == false
|
327
|
+
EnumMock7.new.respond_to?(:category_key).should == true
|
328
|
+
EnumMock7.new.respond_to?(:category_id_key).should == false
|
329
|
+
end
|
330
|
+
|
331
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
describe SelectableAttr::Enum do
|
5
|
+
|
6
|
+
Enum1 = SelectableAttr::Enum.new do
|
7
|
+
entry 1, :book, '書籍'
|
8
|
+
entry 2, :dvd, 'DVD'
|
9
|
+
entry 3, :cd, 'CD'
|
10
|
+
entry 4, :vhs, 'VHS'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "test_define" do
|
14
|
+
Enum1[1].id.should == 1
|
15
|
+
Enum1[2].id.should == 2
|
16
|
+
Enum1[3].id.should == 3
|
17
|
+
Enum1[4].id.should == 4
|
18
|
+
Enum1[1].key.should == :book
|
19
|
+
Enum1[2].key.should == :dvd
|
20
|
+
Enum1[3].key.should == :cd
|
21
|
+
Enum1[4].key.should == :vhs
|
22
|
+
Enum1[1].name.should == '書籍'
|
23
|
+
Enum1[2].name.should == 'DVD'
|
24
|
+
Enum1[3].name.should == 'CD'
|
25
|
+
Enum1[4].name.should == 'VHS'
|
26
|
+
|
27
|
+
Enum1[:book].id.should == 1
|
28
|
+
Enum1[:dvd ].id.should == 2
|
29
|
+
Enum1[:cd ].id.should == 3
|
30
|
+
Enum1[:vhs ].id.should == 4
|
31
|
+
Enum1[:book].key.should == :book
|
32
|
+
Enum1[:dvd ].key.should == :dvd
|
33
|
+
Enum1[:cd ].key.should == :cd
|
34
|
+
Enum1[:vhs ].key.should == :vhs
|
35
|
+
Enum1[:book].name.should == '書籍'
|
36
|
+
Enum1[:dvd].name.should == 'DVD'
|
37
|
+
Enum1[:cd].name.should == 'CD'
|
38
|
+
Enum1[:vhs].name.should == 'VHS'
|
39
|
+
|
40
|
+
Enum1.values.should == [['書籍', 1], ['DVD', 2], ['CD', 3], ['VHS', 4]]
|
41
|
+
Enum1.values(:name, :id).should == [['書籍', 1], ['DVD', 2], ['CD', 3], ['VHS', 4]]
|
42
|
+
Enum1.values(:name, :key).should == [['書籍', :book], ['DVD', :dvd], ['CD', :cd], ['VHS', :vhs]]
|
43
|
+
end
|
44
|
+
|
45
|
+
InetAccess = SelectableAttr::Enum.new do
|
46
|
+
entry 1, :email, 'Eメール', :protocol => 'mailto:'
|
47
|
+
entry 2, :website, 'ウェブサイト', :protocol => 'http://'
|
48
|
+
entry 3, :ftp, 'FTP', :protocol => 'ftp://'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "test_define_with_options" do
|
52
|
+
InetAccess[1].id.should == 1
|
53
|
+
InetAccess[2].id.should == 2
|
54
|
+
InetAccess[3].id.should == 3
|
55
|
+
InetAccess[1].key.should == :email
|
56
|
+
InetAccess[2].key.should == :website
|
57
|
+
InetAccess[3].key.should == :ftp
|
58
|
+
|
59
|
+
|
60
|
+
InetAccess[1].name.should == 'Eメール'
|
61
|
+
InetAccess[2].name.should == 'ウェブサイト'
|
62
|
+
InetAccess[3].name.should == 'FTP'
|
63
|
+
InetAccess[1][:protocol].should == 'mailto:'
|
64
|
+
InetAccess[2][:protocol].should == 'http://'
|
65
|
+
InetAccess[3][:protocol].should == 'ftp://'
|
66
|
+
|
67
|
+
InetAccess[9].id.should be_nil
|
68
|
+
InetAccess[9].key.should be_nil
|
69
|
+
InetAccess[9].name.should be_nil
|
70
|
+
InetAccess[9][:protocol].should be_nil
|
71
|
+
InetAccess[9][:xxxx].should be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
it "test_get_by_option" do
|
75
|
+
InetAccess[:protocol => 'mailto:'].should == InetAccess[1]
|
76
|
+
InetAccess[:protocol => 'http://'].should == InetAccess[2]
|
77
|
+
InetAccess[:protocol => 'ftp://'].should == InetAccess[3]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "test_null?" do
|
81
|
+
InetAccess[1].null?.should == false
|
82
|
+
InetAccess[2].null?.should == false
|
83
|
+
InetAccess[3].null?.should == false
|
84
|
+
InetAccess[9].null?.should == true
|
85
|
+
InetAccess[:protocol => 'mailto:'].null?.should == false
|
86
|
+
InetAccess[:protocol => 'http://'].null?.should == false
|
87
|
+
InetAccess[:protocol => 'ftp://'].null?.should == false
|
88
|
+
InetAccess[:protocol => 'svn://'].null?.should == true
|
89
|
+
end
|
90
|
+
|
91
|
+
it "test_null_object?" do
|
92
|
+
InetAccess[1].null_object?.should == false
|
93
|
+
InetAccess[2].null_object?.should == false
|
94
|
+
InetAccess[3].null_object?.should == false
|
95
|
+
InetAccess[9].null_object?.should == true
|
96
|
+
InetAccess[:protocol => 'mailto:'].null_object?.should == false
|
97
|
+
InetAccess[:protocol => 'http://'].null_object?.should == false
|
98
|
+
InetAccess[:protocol => 'ftp://'].null_object?.should == false
|
99
|
+
InetAccess[:protocol => 'svn://'].null_object?.should == true
|
100
|
+
end
|
101
|
+
|
102
|
+
it "test_to_hash_array" do
|
103
|
+
Enum1.to_hash_array.should == [
|
104
|
+
{:id => 1, :key => :book, :name => '書籍'},
|
105
|
+
{:id => 2, :key => :dvd, :name => 'DVD'},
|
106
|
+
{:id => 3, :key => :cd, :name => 'CD'},
|
107
|
+
{:id => 4, :key => :vhs, :name => 'VHS'}
|
108
|
+
]
|
109
|
+
|
110
|
+
InetAccess.to_hash_array.should == [
|
111
|
+
{:id => 1, :key => :email, :name => 'Eメール', :protocol => 'mailto:'},
|
112
|
+
{:id => 2, :key => :website, :name => 'ウェブサイト', :protocol => 'http://'},
|
113
|
+
{:id => 3, :key => :ftp, :name => 'FTP', :protocol => 'ftp://'}
|
114
|
+
]
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$KCODE='u'
|
2
|
+
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
+
require File.join(File.dirname(__FILE__), '..', 'init')
|
5
|
+
|
6
|
+
def assert_hash(expected, actual)
|
7
|
+
keys = (expected.keys + actual.keys).uniq
|
8
|
+
keys.each do |key|
|
9
|
+
assert_equal expected[key], actual[key], "unmatch value for #{key.inspect}"
|
10
|
+
end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: akm-selectable_attr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Takeshi Akima
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-27 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: selectable_attr generates extra methods dynamically for attribute which has options
|
17
|
+
email: akima@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- VERSION.yml
|
26
|
+
- lib/selectable_attr
|
27
|
+
- lib/selectable_attr/base.rb
|
28
|
+
- lib/selectable_attr/enum.rb
|
29
|
+
- lib/selectable_attr/version.rb
|
30
|
+
- lib/selectable_attr.rb
|
31
|
+
- spec/selectable_attr_base_alias_spec.rb
|
32
|
+
- spec/selectable_attr_enum_spec.rb
|
33
|
+
- spec/spec_helper.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://github.com/akm/selectable_attr/
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --inline-source
|
39
|
+
- --charset=UTF-8
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 1.2.0
|
58
|
+
signing_key:
|
59
|
+
specification_version: 2
|
60
|
+
summary: selectable_attr generates extra methods dynamically
|
61
|
+
test_files: []
|
62
|
+
|