simple_enum 1.6.9 → 2.3.2

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +9 -6
  4. data/LICENSE +1 -1
  5. data/README.md +331 -0
  6. data/Rakefile +9 -17
  7. data/lib/simple_enum/accessors/accessor.rb +61 -0
  8. data/lib/simple_enum/accessors/ignore_accessor.rb +11 -0
  9. data/lib/simple_enum/accessors/whiny_accessor.rb +12 -0
  10. data/lib/simple_enum/accessors.rb +28 -0
  11. data/lib/simple_enum/attribute.rb +109 -0
  12. data/lib/simple_enum/enum.rb +58 -0
  13. data/lib/simple_enum/hasher.rb +26 -0
  14. data/lib/simple_enum/mongoid.rb +16 -18
  15. data/lib/simple_enum/railtie.rb +17 -0
  16. data/lib/simple_enum/translation.rb +21 -0
  17. data/lib/simple_enum/version.rb +2 -2
  18. data/lib/simple_enum/view_helpers.rb +55 -0
  19. data/lib/simple_enum.rb +22 -278
  20. data/simple_enum.gemspec +9 -9
  21. data/spec/simple_enum/accessors_spec.rb +298 -0
  22. data/spec/simple_enum/attribute_spec.rb +272 -0
  23. data/spec/simple_enum/enum_spec.rb +136 -0
  24. data/spec/simple_enum/hasher_spec.rb +63 -0
  25. data/spec/simple_enum/mongoid_spec.rb +44 -0
  26. data/spec/simple_enum/translation_spec.rb +70 -0
  27. data/spec/simple_enum/view_helpers_spec.rb +71 -0
  28. data/spec/spec_helper.rb +27 -0
  29. data/spec/support/active_record_support.rb +27 -0
  30. data/spec/support/i18n_support.rb +12 -0
  31. data/spec/support/model_support.rb +47 -0
  32. data/spec/support/mongoid_support.rb +47 -0
  33. metadata +55 -57
  34. data/README.rdoc +0 -293
  35. data/lib/simple_enum/enum_hash.rb +0 -64
  36. data/lib/simple_enum/validation.rb +0 -58
  37. data/locales/en.yml +0 -10
  38. data/test/array_conversions_test.rb +0 -21
  39. data/test/class_methods_test.rb +0 -114
  40. data/test/dirty_attributes_test.rb +0 -37
  41. data/test/enum_hash_test.rb +0 -73
  42. data/test/finders_test.rb +0 -45
  43. data/test/locales.yml +0 -25
  44. data/test/mongoid_test.rb +0 -66
  45. data/test/object_backed_test.rb +0 -61
  46. data/test/orm/active_record.rb +0 -114
  47. data/test/orm/common.rb +0 -23
  48. data/test/orm/mongoid.rb +0 -114
  49. data/test/poro_test.rb +0 -20
  50. data/test/prefixes_test.rb +0 -36
  51. data/test/simple_enum_test.rb +0 -314
  52. data/test/test_helper.rb +0 -40
  53. data/test/without_shortcuts_test.rb +0 -39
@@ -0,0 +1,298 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleEnum::Accessors do
4
+ let(:enum) { SimpleEnum::Enum.new(:gender, "male" => 0, "female" => 1) }
5
+ fake_model(:klass)
6
+ let(:object) { klass.new }
7
+
8
+ context '.accessor' do
9
+ it 'returns Accessor instance' do
10
+ expect(described_class.accessor(:gender, enum)).to be_a(described_class::Accessor)
11
+ end
12
+
13
+ it 'returns a WhinyAccessor instance if accessor: :whiny' do
14
+ expect(described_class.accessor(:gender, enum, accessor: :whiny)).to be_a(described_class::WhinyAccessor)
15
+ end
16
+
17
+ it 'sets source to "gender" if source: :gender' do
18
+ expect(described_class.accessor(:gender, enum, source: :gender).source).to eq 'gender'
19
+ end
20
+ end
21
+
22
+ context '.register_accessor' do
23
+ let(:accessor) { Class.new { def initialize(*args); end } }
24
+ subject { described_class.accessor(:gender, "enum", accessor: :would_be) }
25
+
26
+ before { SimpleEnum.register_accessor :would_be, accessor }
27
+ after { SimpleEnum::Accessors::ACCESSORS.delete(:would_be) }
28
+
29
+ it 'adds accessor to ACCESSORS' do
30
+ expect(SimpleEnum::Accessors::ACCESSORS[:would_be]).to eq accessor
31
+ end
32
+
33
+ it 'allows to create an instance of our WouldBeAccessor' do
34
+ expect(subject).to be_a accessor
35
+ end
36
+ end
37
+
38
+ context 'Accessor' do
39
+ subject { described_class::Accessor.new(:gender, enum) }
40
+
41
+ context '#name' do
42
+ it 'returns the enum name as string' do
43
+ expect(subject.name).to eq 'gender'
44
+ end
45
+ end
46
+
47
+ context '#to_s' do
48
+ it 'returns the name' do
49
+ expect(subject.to_s).to eq 'gender'
50
+ end
51
+ end
52
+
53
+ context '#prefix' do
54
+ it 'returns empty string when prefix is nil' do
55
+ expect(described_class::Accessor.new(:gender, enum).prefix).to eq ''
56
+ end
57
+
58
+ it 'returns gender_ when prefix is true' do
59
+ expect(described_class::Accessor.new(:gender, enum, nil, true).prefix).to eq 'gender_'
60
+ end
61
+
62
+ it 'returns other_ when prefix is "other"' do
63
+ expect(described_class::Accessor.new(:gender, hash, nil, 'other').prefix).to eq 'other_'
64
+ end
65
+ end
66
+
67
+ context '#source' do
68
+ it 'returns gender_cd when source is nil' do
69
+ expect(described_class::Accessor.new(:gender, hash, nil).source).to eq 'gender_cd'
70
+ end
71
+
72
+ it 'returns "some_column" when source is set to :some_column' do
73
+ expect(described_class::Accessor.new(:gender, hash, :some_column).source).to eq 'some_column'
74
+ end
75
+
76
+ it 'returns "gender" when source is set to "gender"' do
77
+ expect(described_class::Accessor.new(:gender, hash, 'gender').source).to eq 'gender'
78
+ end
79
+ end
80
+
81
+ context '#read' do
82
+ shared_examples_for 'reading an enum' do
83
+ it 'returns nil then gender_cd is nil' do
84
+ expect(subject.read(object)).to be_nil
85
+ end
86
+
87
+ it 'returns :male when gender_cd is 0' do
88
+ expect(subject.read(klass.new(0))).to eq :male
89
+ end
90
+
91
+ it 'returns :female when gender_cd is 1' do
92
+ expect(subject.read(klass.new(1))).to eq :female
93
+ end
94
+ end
95
+
96
+ it_behaves_like 'reading an enum'
97
+
98
+ context 'with name == source' do
99
+ subject { described_class::Accessor.new(:gender_cd, enum, :gender_cd) }
100
+ it_behaves_like 'reading an enum'
101
+ end
102
+ end
103
+
104
+ context '#write' do
105
+ shared_examples_for 'writing an enum' do
106
+ it 'writes nil to object' do
107
+ object = klass.new(0)
108
+ expect(subject.write(object, nil)).to be_nil
109
+ expect(object.gender_cd).to be_nil
110
+ end
111
+
112
+ it 'writes 1 to object with :female' do
113
+ expect(subject.write(object, :female)).to eq :female
114
+ expect(object.gender_cd).to eq 1
115
+ end
116
+
117
+ it 'writes 0 to object with "male"' do
118
+ expect(subject.write(object, 'male')).to eq 'male'
119
+ expect(object.gender_cd).to eq 0
120
+ end
121
+
122
+ it 'writes 1 to object with 1' do
123
+ expect(subject.write(object, 1)).to eq 1
124
+ expect(object.gender_cd).to eq 1
125
+ end
126
+
127
+ it 'writes nil to object with :other' do
128
+ object = klass.new(1)
129
+ expect(subject.write(object, :other)).to be_nil
130
+ expect(object.gender_cd).to be_nil
131
+ end
132
+ end
133
+
134
+ it_behaves_like 'writing an enum'
135
+
136
+ context 'with name == source' do
137
+ subject { described_class::Accessor.new(:gender_cd, enum, :gender_cd) }
138
+ it_behaves_like 'writing an enum'
139
+ end
140
+ end
141
+
142
+ context '#selected?' do
143
+ it 'returns false when gender_cd is nil' do
144
+ expect(subject.selected?(object)).to be_falsey
145
+ expect(subject.selected?(object, :male)).to be_falsey
146
+ end
147
+
148
+ it 'returns true when gender_cd is != nil' do
149
+ expect(subject.selected?(klass.new(0))).to be_truthy
150
+ expect(subject.selected?(klass.new(1))).to be_truthy
151
+ end
152
+
153
+ it 'returns true when gender_cd is 0 and :male is passed' do
154
+ expect(subject.selected?(klass.new(0), :male)).to be_truthy
155
+ end
156
+
157
+ it 'returns false when gender_cd is 0 and :female is passed' do
158
+ expect(subject.selected?(klass.new(0), :female)).to be_falsey
159
+ end
160
+
161
+ it 'returns false when gender_cd is 1 and :other is passed' do
162
+ expect(subject.selected?(klass.new(0), :other)).to be_falsey
163
+ end
164
+ end
165
+
166
+ context '#changed?' do
167
+ it 'delegates to attribute_changed?' do
168
+ expect(object).to receive(:attribute_changed?).with('gender_cd') { true }
169
+ expect(subject.changed?(object)).to be_truthy
170
+ end
171
+ end
172
+
173
+ context '#was' do
174
+ let(:changes) do
175
+ { 'gender_cd' => 1 }
176
+ end
177
+
178
+ it 'delegates to changed_attributes and resolves symbol' do
179
+ expect(object).to receive(:changed_attributes) { changes }
180
+ expect(subject.was(object)).to eq :female
181
+ end
182
+ end
183
+ end
184
+
185
+ context 'dirty attributes on ActiveModel', active_record: true do
186
+ fake_active_record(:klass) { as_enum :gender, %w{male female} }
187
+ let(:object) { klass.create(gender: :male) }
188
+
189
+ it 'does not raise error "private method attribute_was called"' do
190
+ object.gender = :female
191
+ expect do
192
+ expect(object.gender_changed?).to be_truthy
193
+ expect(object.gender_was).to eq :male
194
+ end.to_not raise_error
195
+ end
196
+
197
+ context 'github.com/lwe/simple_enum/issues/109' do
198
+ fake_active_record(:klass) {
199
+ as_enum(:gender_cd, %w{female male}, source: :gender_cd)
200
+ as_enum(:role_cd, %w{completed cap dnf dns}, map: :string, source: :role_cd)
201
+ }
202
+ let(:object) { klass.create(role_cd: "cap", gender_cd: :female) }
203
+
204
+ context '#gender_cd_was' do
205
+ it 'returns nil when nil' do
206
+ expect(klass.create.gender_cd_was).to be_nil
207
+ end
208
+
209
+ it 'returns the current gender' do
210
+ expect(object.gender_cd_was).to eq :female
211
+ end
212
+
213
+ it 'returns the old gender' do
214
+ object.gender_cd = :male
215
+ expect(object.gender_cd_was).to eq :female
216
+ end
217
+ end
218
+
219
+ context '#role_cd_was' do
220
+ it 'returns nil when nil' do
221
+ expect(klass.create.role_cd_was).to be_nil
222
+ end
223
+
224
+ it 'returns the current role' do
225
+ expect(object.role_cd_was).to eq :cap
226
+ end
227
+
228
+ it 'returns completed when changed' do
229
+ object.role_cd = :completed
230
+ expect(object.role_cd_was).to eq :cap
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ context '#scope' do
237
+ fake_active_record(:klass) { as_enum :gender, [:male, :female] }
238
+ let(:accessor) { described_class::Accessor.new(:gender, enum) }
239
+ subject { accessor.scope(klass, 1) }
240
+
241
+ it 'returns an ActiveRecord::Relation' do
242
+ expect(subject).to be_a(ActiveRecord::Relation)
243
+ end
244
+
245
+ it "queries for gender_cd = 1" do
246
+ values_hash = { "gender_cd" => 1 }
247
+ expect(subject.where_values_hash).to eq values_hash
248
+ end
249
+ end
250
+
251
+ context 'IgnoreAccessor' do
252
+ subject { described_class::IgnoreAccessor.new(:gender, enum) }
253
+
254
+ it 'sets gender_cd to 0 with symbol' do
255
+ expect(subject.write(object, :male)).to_not be_falsey
256
+ expect(object.gender_cd).to eq 0
257
+ end
258
+
259
+ it 'sets gender_cd to 1 via value (1)' do
260
+ expect(subject.write(object, 1)).to_not be_falsey
261
+ expect(object.gender_cd).to eq 1
262
+ end
263
+
264
+ it 'sets gender_cd to nil' do
265
+ expect(subject.write(object, nil)).to be_falsey
266
+ expect(object.gender_cd).to be_nil
267
+ end
268
+
269
+ it 'keeps existing value when unknown value is passed' do
270
+ object.gender_cd = 1
271
+ expect(subject.write(object, :other)).to be_falsey
272
+ expect(object.gender_cd).to eq 1
273
+ end
274
+ end
275
+
276
+ context 'WhinyAccessor' do
277
+ subject { described_class::WhinyAccessor.new(:gender, enum) }
278
+
279
+ it 'raises no error when setting existing key' do
280
+ expect { subject.write(object, :male) }.to_not raise_error
281
+ expect(object.gender_cd).to eq 0
282
+ end
283
+
284
+ it 'raises no error when setting with existing value' do
285
+ expect { subject.write(object, 1) }.to_not raise_error
286
+ expect(object.gender_cd).to eq 1
287
+ end
288
+
289
+ it 'raises no error when setting to nil' do
290
+ expect { subject.write(object, nil) }.to_not raise_error
291
+ expect(object.gender_cd).to be_nil
292
+ end
293
+
294
+ it 'raises ArgumentError when setting invalid key' do
295
+ expect { subject.write(object, :other) }.to raise_error(ArgumentError)
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,272 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleEnum::Attribute do
4
+ fake_model(:klass) { as_enum :gender, %w{male female}, with: [] }
5
+ let(:accessor) { subject.class.genders_accessor }
6
+
7
+ context '.as_enum' do
8
+ it 'returns a SimpleEnum::Enum' do
9
+ expect(klass.as_enum(:gender, %w{male female})).to be_a(SimpleEnum::Enum)
10
+ end
11
+ end
12
+
13
+ context '.register_generator' do
14
+ let(:mod) {
15
+ Module.new do
16
+ def generate_enum_spec_extension_for(enum, accessor)
17
+ module_eval { attr_accessor :some_reader }
18
+ simple_enum_module.module_eval do
19
+ define_method("extension_method") { "as_enum(#{enum.name})" }
20
+ end
21
+ end
22
+ end
23
+ }
24
+
25
+ before { SimpleEnum.register_generator :spec, mod }
26
+ after { described_class::EXTENSIONS.clear }
27
+
28
+ subject { klass.new }
29
+
30
+ it 'adds "spec" to EXTENSIONS' do
31
+ expect(described_class::EXTENSIONS).to eq %w{spec}
32
+ end
33
+
34
+ it 'calls generate_enum_spec_extension_for during as_enum' do
35
+ expect(subject.extension_method).to eq "as_enum(gender)"
36
+ end
37
+
38
+ it 'allows to add behavior to class itself (e.g. attr_accessor)' do
39
+ subject.some_reader = "some value"
40
+ expect(subject.some_reader).to eq "some value"
41
+ end
42
+ end
43
+
44
+ context 'generate_enum_class_accessors_for' do
45
+ context '.genders' do
46
+ subject { klass.genders }
47
+
48
+ it 'returns a SimpleEnum::Enum' do
49
+ expect(subject).to be_a(SimpleEnum::Enum)
50
+ end
51
+ end
52
+
53
+ context '.genders_accessor' do
54
+ subject { klass.genders_accessor }
55
+
56
+ it 'returns a SimpleEnum::Accessor' do
57
+ expect(subject).to be_a(SimpleEnum::Accessors::Accessor)
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'generate_enum_instance_accessors_for' do
63
+ subject { klass.new(1) }
64
+
65
+ context '#gender' do
66
+ it 'delegates to accessor' do
67
+ expect(accessor).to receive(:read).with(subject) { :female }
68
+ expect(subject.gender).to eq :female
69
+ end
70
+ end
71
+
72
+ context '#gender=' do
73
+ it 'delegates to accessor' do
74
+ expect(accessor).to receive(:write).with(subject, :male) { 0 }
75
+ subject.gender = :male
76
+ end
77
+ end
78
+
79
+ context '#gender?' do
80
+ it 'delegates to accessor' do
81
+ expect(accessor).to receive(:selected?).with(subject, nil) { nil }
82
+ expect(subject.gender?).to be_falsey
83
+ end
84
+ end
85
+ end
86
+
87
+ context 'generate_enum_dirty_methods_for' do
88
+ subject { klass.new }
89
+
90
+ it 'does not respond to #gender_changed?' do
91
+ expect(subject).to_not respond_to(:gender_changed?)
92
+ end
93
+
94
+ it 'does not responds to #gender_was' do
95
+ expect(subject).to_not respond_to(:gender_was)
96
+ end
97
+
98
+ context 'with: :dirty' do
99
+ fake_model(:klass_with_dirty) { as_enum :gender, %w{male female}, with: [:dirty] }
100
+ subject { klass_with_dirty.new }
101
+
102
+ it 'delegates #gender_changed? to accessor' do
103
+ expect(accessor).to receive(:changed?).with(subject) { true }
104
+ expect(subject.gender_changed?).to be_truthy
105
+ end
106
+
107
+ it 'delegates #gender_was to accesso' do
108
+ expect(accessor).to receive(:was).with(subject) { :female }
109
+ expect(subject.gender_was).to eq :female
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'generate_enum_attribute_methods_for' do
115
+ subject { klass.new }
116
+
117
+ it 'does not respond to #male? or #female?' do
118
+ expect(subject).to_not respond_to(:male?)
119
+ expect(subject).to_not respond_to(:female?)
120
+ end
121
+
122
+ it 'does not respond to #male! or #female!' do
123
+ expect(subject).to_not respond_to(:male!)
124
+ expect(subject).to_not respond_to(:female!)
125
+ end
126
+
127
+ context 'with: :attribute' do
128
+ fake_model(:klass_with_attributes) { as_enum :gender, %w{male female}, with: [:attribute] }
129
+ subject { klass_with_attributes.new }
130
+
131
+ it 'delegates #gender? to accessor' do
132
+ expect(accessor).to receive(:selected?).with(subject, nil) { :female }
133
+ expect(subject.gender?).to be_truthy
134
+ end
135
+
136
+ it 'delegates #male? to accessor' do
137
+ expect(accessor).to receive(:selected?).with(subject, 'male') { true }
138
+ expect(subject.male?).to be_truthy
139
+ end
140
+
141
+ it 'delegates #female? to accessor' do
142
+ expect(accessor).to receive(:selected?).with(subject, 'female') { false }
143
+ expect(subject.female?).to be_falsey
144
+ end
145
+
146
+ it 'delegates #male! to accessor' do
147
+ expect(accessor).to receive(:write).with(subject, 'male') { 0 }
148
+ expect(subject.male!).to eq 0
149
+ end
150
+
151
+ it 'delegates #female! to accessor' do
152
+ expect(accessor).to receive(:write).with(subject, 'female') { 1 }
153
+ expect(subject.female!).to eq 1
154
+ end
155
+ end
156
+
157
+ context 'with a prefix' do
158
+ fake_model(:klass_with_prefix) { as_enum :gender, %w{male female}, with: [:attribute], prefix: true }
159
+ subject { klass_with_prefix.new }
160
+
161
+ it 'delegates #gender? to accessor' do
162
+ expect(accessor).to receive(:selected?).with(subject, nil) { :female }
163
+ expect(subject.gender?).to be_truthy
164
+ end
165
+
166
+ it 'delegates #gender_male? to accessor' do
167
+ expect(accessor).to receive(:selected?).with(subject, 'male') { true }
168
+ expect(subject.gender_male?).to be_truthy
169
+ end
170
+
171
+ it 'delegates #gender_female? to accessor' do
172
+ expect(accessor).to receive(:selected?).with(subject, 'female') { false }
173
+ expect(subject.gender_female?).to be_falsey
174
+ end
175
+
176
+ it 'delegates #gender_male! to accessor' do
177
+ expect(accessor).to receive(:write).with(subject, 'male') { 0 }
178
+ expect(subject.gender_male!).to eq 0
179
+ end
180
+
181
+ it 'delegates #gender_female! to accessor' do
182
+ expect(accessor).to receive(:write).with(subject, 'female') { 1 }
183
+ expect(subject.gender_female!).to eq 1
184
+ end
185
+ end
186
+ end
187
+
188
+ context 'generate_enum_scope_methods_for', active_record: true do
189
+ fake_active_record(:klass) {
190
+ as_enum :gender, [:male, :female], with: [:scope]
191
+ }
192
+
193
+ let(:accessor) { klass.genders_accessor }
194
+
195
+ shared_examples_for 'delegates to accessor#scope' do |value|
196
+ it 'delegates to #scope' do
197
+ expect(accessor).to receive(:scope).with(klass, value)
198
+ subject
199
+ end
200
+ end
201
+
202
+ context '.males' do
203
+ subject { klass.males }
204
+ it_behaves_like 'delegates to accessor#scope', 0
205
+ end
206
+
207
+ context '.females' do
208
+ subject { klass.females }
209
+ it_behaves_like 'delegates to accessor#scope', 1
210
+ end
211
+
212
+ context 'with prefix' do
213
+ fake_active_record(:klass) {
214
+ as_enum :gender, [:male, :female], with: [:scope], prefix: true
215
+ }
216
+
217
+ context '.gender_males' do
218
+ subject { klass.gender_males }
219
+ it_behaves_like 'delegates to accessor#scope', 0
220
+ end
221
+
222
+ context '.gender_females' do
223
+ subject { klass.gender_females }
224
+ it_behaves_like 'delegates to accessor#scope', 1
225
+ end
226
+
227
+ context 'and pluralize scopes option is set to false' do
228
+ fake_active_record(:klass) {
229
+ as_enum :gender, [:male, :female], with: [:scope], prefix: true, pluralize_scopes: false
230
+ }
231
+
232
+ context '.gender_male' do
233
+ subject { klass.gender_male }
234
+ it_behaves_like 'delegates to accessor#scope', 0
235
+ end
236
+
237
+ context '.gender_female' do
238
+ subject { klass.gender_female }
239
+ it_behaves_like 'delegates to accessor#scope', 1
240
+ end
241
+ end
242
+ end
243
+
244
+ context 'when pluralize scopes option is set to false' do
245
+ fake_active_record(:klass) {
246
+ as_enum :gender, [:male, :female], with: [:scope], pluralize_scopes: false
247
+ }
248
+
249
+ context '.male' do
250
+ subject { klass.male }
251
+ it_behaves_like 'delegates to accessor#scope', 0
252
+ end
253
+
254
+ context '.female' do
255
+ subject { klass.female }
256
+ it_behaves_like 'delegates to accessor#scope', 1
257
+ end
258
+ end
259
+
260
+ context 'without scope method' do
261
+ fake_model(:klass_without_scope_method) {
262
+ as_enum :gender, [:male, :female], with: [:scope]
263
+ }
264
+ subject { klass_without_scope_method }
265
+
266
+ it 'does not add .males nor .females' do
267
+ expect(subject).to_not respond_to(:males)
268
+ expect(subject).to_not respond_to(:females)
269
+ end
270
+ end
271
+ end
272
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleEnum::Enum do
4
+ let(:hash) do
5
+ { "male" => 0, "female" => 1 }
6
+ end
7
+
8
+ fake_model(:klass)
9
+ let(:object) { klass.new }
10
+
11
+ subject { described_class.new(:gender, hash) }
12
+
13
+ context '#name' do
14
+ it 'returns the enum name as string' do
15
+ expect(subject.name).to eq 'gender'
16
+ end
17
+ end
18
+
19
+ context '#to_s' do
20
+ it 'returns the name' do
21
+ expect(subject.to_s).to eq 'gender'
22
+ end
23
+ end
24
+
25
+ context '#hash' do
26
+ subject { described_class.new(:gender, hash).hash }
27
+
28
+ it 'returns hash that was set in the constructor' do
29
+ expect(subject).to be_a(Hash)
30
+ expect(subject.keys).to eq %w{male female}
31
+ expect(subject.values).to eq [0, 1]
32
+ end
33
+ end
34
+
35
+ context '#keys' do
36
+ it 'returns the keys in the order added' do
37
+ expect(subject.keys).to eq %w{male female}
38
+ end
39
+ end
40
+
41
+ context '#values' do
42
+ it 'returns the values in the order added' do
43
+ expect(subject.values).to eq [0, 1]
44
+ end
45
+ end
46
+
47
+ context '#each_pair (aliased to #each)' do
48
+ it 'yields twice with #each_pair' do
49
+ expect { |b| subject.each_pair(&b) }.to yield_control.exactly(2).times
50
+ end
51
+
52
+ it 'yields twice with #each' do
53
+ expect { |b| subject.each(&b) }.to yield_control.exactly(2).times
54
+ end
55
+ end
56
+
57
+ context '#value (aliased to #[])' do
58
+ it 'looks up by string' do
59
+ expect(subject.value('male')).to eq 0
60
+ expect(subject['male']).to eq 0
61
+ end
62
+
63
+ it 'looks up by symbol' do
64
+ expect(subject.value(:female)).to eq 1
65
+ expect(subject[:female]).to eq 1
66
+ end
67
+
68
+ it 'looks up by value' do
69
+ expect(subject.value(0)).to be 0
70
+ expect(subject[0]).to be 0
71
+ end
72
+
73
+ it 'returns nil when key is not found' do
74
+ expect(subject.value(:inexistent)).to be_nil
75
+ expect(subject[:inexistent]).to be_nil
76
+ end
77
+ end
78
+
79
+ context '#fetch' do
80
+ it 'looks up by string' do
81
+ expect(subject.fetch('male')).to eq 0
82
+ end
83
+
84
+ it 'looks up by symbol' do
85
+ expect(subject.fetch(:female)).to eq 1
86
+ end
87
+
88
+ it 'looks up by value' do
89
+ expect(subject.fetch(0)).to be 0
90
+ end
91
+
92
+ it 'throws exception when key is not found' do
93
+ expect{subject.fetch(:inexistent)}.to raise_error(/not found/i)
94
+ end
95
+ end
96
+
97
+ context '#key' do
98
+ it 'returns symbolized key for supplied value' do
99
+ expect(subject.key(0)).to eq :male
100
+ expect(subject.key(1)).to eq :female
101
+ end
102
+
103
+ it 'returns nil if value is not found' do
104
+ expect(subject.key(12)).to be_nil
105
+ end
106
+ end
107
+
108
+ context '#include?' do
109
+ it 'returns true by string' do
110
+ expect(subject.include?('male')).to be_truthy
111
+ end
112
+
113
+ it 'returns true by symbol' do
114
+ expect(subject.include?(:female)).to be_truthy
115
+ end
116
+
117
+ it 'returns true by checking actual value' do
118
+ expect(subject.include?(1)).to be_truthy
119
+ end
120
+
121
+ it 'returns false when neither in keys nor values' do
122
+ expect(subject.include?(:other)).to be_falsey
123
+ expect(subject.include?(2)).to be_falsey
124
+ end
125
+ end
126
+
127
+ context '#values_at' do
128
+ it 'fetches multiple values by string' do
129
+ expect(subject.values_at("male", "female")).to eq [0, 1]
130
+ end
131
+
132
+ it 'fetches multiple values by symbol' do
133
+ expect(subject.values_at(:male)).to eq [0]
134
+ end
135
+ end
136
+ end