simple_enum 2.0.0 → 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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/LICENSE +1 -1
- data/README.md +102 -19
- data/Rakefile +13 -4
- data/lib/simple_enum/accessors/accessor.rb +8 -2
- data/lib/simple_enum/accessors.rb +10 -0
- data/lib/simple_enum/attribute.rb +37 -5
- data/lib/simple_enum/enum.rb +13 -0
- data/lib/simple_enum/mongoid.rb +5 -3
- data/lib/simple_enum/translation.rb +2 -0
- data/lib/simple_enum/version.rb +1 -1
- data/lib/simple_enum/view_helpers.rb +16 -0
- data/lib/simple_enum.rb +3 -0
- data/simple_enum.gemspec +1 -1
- data/spec/simple_enum/accessors_spec.rb +101 -15
- data/spec/simple_enum/attribute_spec.rb +80 -19
- data/spec/simple_enum/enum_spec.rb +39 -5
- data/spec/simple_enum/translation_spec.rb +4 -0
- data/spec/simple_enum/view_helpers_spec.rb +9 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/support/i18n_support.rb +1 -1
- data/spec/support/mongoid_support.rb +33 -7
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ead9e5d2a63ed29727c934fa36cf37a544dacd65
|
4
|
+
data.tar.gz: 89da3f9fa8ee6e7ef19f028bed68167d8e592f55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 834dd3a7c5e92d44c0317ac88356af38a56fdc0581dd4b4101583dbb494f0fa1d027e88f2bd1d9d134783bab08171ff998d604d78db5ce3588cec24c301f4b1e
|
7
|
+
data.tar.gz: a4947957c71ddeb731981403288daea009f8e6b565657cf04a140de9201cf507e2f0c81490981b2d481f903035ac608572c89e3b62b8b4499d671775f4ffa6a9
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
SimpleEnum
|
2
2
|
==========
|
3
3
|
|
4
|
+
[](https://badge.fury.io/rb/simple_enum)
|
4
5
|
[](https://travis-ci.org/lwe/simple_enum)
|
5
|
-
[](https://codeclimate.com/github/lwe/simple_enum)
|
6
7
|
|
7
8
|
Unobtrusive enum-like fields for ActiveRecord and Ruby, brings enums functionality
|
8
9
|
to ActiveRecord and Mongoid models (built for Rails 4+).
|
@@ -50,7 +51,7 @@ to use simple_enum with another version of mongoid, use version 1.6 instead.
|
|
50
51
|
Load mongoid support in the `Gemfile`:
|
51
52
|
|
52
53
|
```ruby
|
53
|
-
gem 'simple_enum', '2.
|
54
|
+
gem 'simple_enum', '~> 2.3.0' , require: 'simple_enum/mongoid'
|
54
55
|
```
|
55
56
|
|
56
57
|
Add this to a model:
|
@@ -96,9 +97,40 @@ joe.gender_cd # => 0
|
|
96
97
|
Accessing actual enum values is possible at the class level:
|
97
98
|
|
98
99
|
```ruby
|
99
|
-
User.genders
|
100
|
-
User.genders[:male]
|
101
|
-
User.
|
100
|
+
User.genders # => #<SimpleEnum::Enum:0x0....>
|
101
|
+
User.genders[:male] # => 0
|
102
|
+
User.genders.values_at(:male, :female) # => [0, 1] (since 2.1.0)
|
103
|
+
User.females # => #<ActiveRecord::Relation:0x0.....> (WHERE gender_cd = 1)
|
104
|
+
```
|
105
|
+
|
106
|
+
By default, scope names are generated as pluralized forms of the defined enum values e.g.
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
class Booking < ActiveRecord::Base
|
110
|
+
as_enum :status, %i{active cancelled pending}
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
114
|
+
would generate the following:
|
115
|
+
```ruby
|
116
|
+
Booking.actives # => #<ActiveRecord::Relation:0x0.....> (WHERE status_cd = 1)
|
117
|
+
Booking.cancelleds # => #<ActiveRecord::Relation:0x0.....> (WHERE status_cd = 2)
|
118
|
+
Booking.pendings # => #<ActiveRecord::Relation:0x0.....> (WHERE status_cd = 3)
|
119
|
+
```
|
120
|
+
|
121
|
+
By setting `pluralize_scopes: false` will not generate pluralized versions of scopes e.g.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
class Booking < ActiveRecord::Base
|
125
|
+
as_enum :status, %i{active cancelled pending}, pluralize_scopes: false
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
would generate the following:
|
130
|
+
```ruby
|
131
|
+
Booking.active # => #<ActiveRecord::Relation:0x0.....> (WHERE status_cd = 1)
|
132
|
+
Booking.cancelled # => #<ActiveRecord::Relation:0x0.....> (WHERE status_cd = 2)
|
133
|
+
Booking.pending # => #<ActiveRecord::Relation:0x0.....> (WHERE status_cd = 3)
|
102
134
|
```
|
103
135
|
|
104
136
|
### Wait, there's more!
|
@@ -112,7 +144,7 @@ User.females # => #<ActiveRecord::Relation:0x0.....> (WHERE gender_cd
|
|
112
144
|
end
|
113
145
|
```
|
114
146
|
|
115
|
-
**Disclaimer**: if you _ever_ decide to reorder this array,
|
147
|
+
**Disclaimer**: if you _ever_ decide to reorder this array, beware that any
|
116
148
|
previous mapping is lost. So it's recommended to create mappings (that might
|
117
149
|
change) using hashes instead of arrays. For stuff like gender it might be
|
118
150
|
probably perfectly fine to use arrays though.
|
@@ -207,9 +239,56 @@ User.females # => #<ActiveRecord::Relation:0x0.....> (WHERE gender_cd
|
|
207
239
|
|
208
240
|
```ruby
|
209
241
|
# See lib/simple_enum.rb for other options
|
210
|
-
SimpleEnum.with = [:
|
242
|
+
SimpleEnum.with = [:attribute, :scope]
|
243
|
+
```
|
244
|
+
|
245
|
+
### View Helpers
|
246
|
+
|
247
|
+
Require translated enum values? See [SimpleEnum::ViewHelpers][VE.rb] for more
|
248
|
+
details and functions. _Disclaimer_: these methods are release candidate quality
|
249
|
+
so expect them to change in future versions of SimpleEnum.
|
250
|
+
|
251
|
+
- Translate the current value in a view:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
translate_enum user, :gender # => "Frau" # assuming :de and translations exist
|
255
|
+
te user, :gender # translate_enum is also aliased to te
|
256
|
+
```
|
257
|
+
|
258
|
+
Provide translations in the i18n yaml file like:
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
de:
|
262
|
+
enums:
|
263
|
+
gender:
|
264
|
+
female: 'Frau'
|
265
|
+
male: 'Mann'
|
211
266
|
```
|
212
267
|
|
268
|
+
- Build a select tag with a translated dropdown and symbol as value:
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
select :user, :gender, enum_option_pairs(User, :gender)
|
272
|
+
```
|
273
|
+
|
274
|
+
- ...and one with the index as value:
|
275
|
+
|
276
|
+
```ruby
|
277
|
+
select :user, :gender_cd, enum_option_pairs(User, :gender, true)
|
278
|
+
```
|
279
|
+
|
280
|
+
## Extensions
|
281
|
+
|
282
|
+
`simple_enum` provides hooks to extend its functionality, starting with 2.3.0
|
283
|
+
the following extensions can be used:
|
284
|
+
|
285
|
+
- **Multi-select enum** support for SimpleEnum:
|
286
|
+
[simple_enum-multiple](https://github.com/bbtfr/simple_enum-multiple)
|
287
|
+
- **Persistence values**, i.e. store values in the DB:
|
288
|
+
[simple_enum-persistence](https://github.com/bbtfr/simple_enum-persistence)
|
289
|
+
- **Scopes**, scopes helper for ActiveRecord enum attributes:
|
290
|
+
[simple_enum-scopes](https://github.com/aovertus/simple_enum-scopes)
|
291
|
+
|
213
292
|
## Best practices
|
214
293
|
|
215
294
|
Do not use values named after existing, or well known method names, like `new`, `create` etc.
|
@@ -219,7 +298,7 @@ Do not use values named after existing, or well known method names, like `new`,
|
|
219
298
|
as_enum :handle, [:new, :create, :update]
|
220
299
|
|
221
300
|
# GOOD, prefixes all methods
|
222
|
-
as_enum :handle, [:new, :create, :update], :
|
301
|
+
as_enum :handle, [:new, :create, :update], prefix: true
|
223
302
|
```
|
224
303
|
|
225
304
|
Searching for certain values by using the finder methods:
|
@@ -231,18 +310,22 @@ User.females # => returns an ActiveRecord::Relation
|
|
231
310
|
Contributors
|
232
311
|
------------
|
233
312
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
313
|
+
- [@dmitry](https://github.com/dmitry) - bugfixes and other improvements
|
314
|
+
- [@tarsolya](https://github.com/tarsolya) - implemented all the ruby 1.9 and rails 3 goodness!
|
315
|
+
- [@dbalatero](https://github.com/dbalatero) - rails 2.3.5 bugfix & validator fixes
|
316
|
+
- [@johnthethird](https://github.com/johnthethird) - feature for `_for_select` to return the values
|
317
|
+
- @sinsiliux - ruby 1.9 fixes and removed AR dependency
|
318
|
+
- [@sled](https://github.com/sled) - mongoid support
|
319
|
+
- [@abrom](https://github.com/abrom) - `find_by_...` method
|
320
|
+
- [@mhuggins](https://github.com/mhuggins) - translations fixes
|
321
|
+
- [@patbenatar](https://github.com/patbenatar) - for helping move towards 2.0 (scopes et all)
|
322
|
+
- [@abacha](https://github.com/abacha) - translation helpers, README fixes
|
323
|
+
- [@bbtfr](https://github.com/bbtfr) - for support, ideas and pushing extensions
|
324
|
+
- and all others: https://github.com/lwe/simple_enum/graphs/contributors thanks
|
244
325
|
|
245
326
|
License & Copyright
|
246
327
|
-------------------
|
247
328
|
|
248
|
-
Copyright (c) 2011-
|
329
|
+
Copyright (c) 2011-2015 by Lukas Westermann, Licensed under MIT License (see LICENSE file)
|
330
|
+
|
331
|
+
[VE.rb]: https://github.com/lwe/simple_enum/blob/master/lib/simple_enum/view_helpers.rb
|
data/Rakefile
CHANGED
@@ -5,11 +5,20 @@ require 'rake/testtask'
|
|
5
5
|
Bundler::GemHelper.install_tasks
|
6
6
|
|
7
7
|
desc 'Default: run all unit tests for both ActiveRecord & Mongoid.'
|
8
|
-
task :default => :spec
|
8
|
+
task :default => :'spec:all'
|
9
9
|
|
10
|
-
desc 'Run
|
11
|
-
task :spec
|
12
|
-
|
10
|
+
desc 'Run basic specs only (skips mongoid)'
|
11
|
+
task :spec => :'spec:basic'
|
12
|
+
|
13
|
+
namespace :spec do
|
14
|
+
desc 'Run all specs'
|
15
|
+
task :all do
|
16
|
+
sh 'bundle', 'exec', 'rspec', 'spec/'
|
17
|
+
end
|
18
|
+
|
19
|
+
task :basic do
|
20
|
+
sh 'bundle', 'exec', 'rspec', 'spec/', '-t', '~mongoid'
|
21
|
+
end
|
13
22
|
end
|
14
23
|
|
15
24
|
# Mongodb
|
@@ -29,11 +29,17 @@ module SimpleEnum
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def changed?(object)
|
32
|
-
object.attribute_changed
|
32
|
+
object.send(:attribute_changed?, source)
|
33
33
|
end
|
34
34
|
|
35
35
|
def was(object)
|
36
|
-
|
36
|
+
changes = object.send(:changed_attributes)
|
37
|
+
key = changes.fetch(source, read_before_type_cast(object))
|
38
|
+
enum.key(key) if key
|
39
|
+
end
|
40
|
+
|
41
|
+
def scope(relation, value)
|
42
|
+
relation.where(source => value)
|
37
43
|
end
|
38
44
|
|
39
45
|
def to_s
|
@@ -15,4 +15,14 @@ module SimpleEnum
|
|
15
15
|
klass.new(name, enum, options[:source], options[:prefix])
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
# Public: Extension method to register a custom accessor.
|
20
|
+
#
|
21
|
+
# key - The Symbol of the accessor key, e.g. `:bitwise`
|
22
|
+
# clazz - The Class with the accessor implementation
|
23
|
+
#
|
24
|
+
# Returns nothing
|
25
|
+
def self.register_accessor(key, clazz)
|
26
|
+
Accessors::ACCESSORS[key] = clazz
|
27
|
+
end
|
18
28
|
end
|
@@ -13,8 +13,11 @@ module SimpleEnum
|
|
13
13
|
# original method.
|
14
14
|
#
|
15
15
|
module Attribute
|
16
|
+
# Registered registrator methods from extensions
|
17
|
+
EXTENSIONS = []
|
18
|
+
|
16
19
|
def as_enum(name, values, options = {})
|
17
|
-
options.assert_valid_keys(:source, :prefix, :with, :accessor, :map)
|
20
|
+
options.assert_valid_keys(:source, :prefix, :with, :accessor, :map, :pluralize_scopes)
|
18
21
|
|
19
22
|
hash = SimpleEnum::Hasher.map(values, options)
|
20
23
|
enum = SimpleEnum::Enum.new(name, hash)
|
@@ -22,9 +25,10 @@ module SimpleEnum
|
|
22
25
|
|
23
26
|
generate_enum_class_accessors_for(enum, accessor)
|
24
27
|
generate_enum_instance_accessors_for(enum, accessor)
|
28
|
+
generate_additional_enum_methods_for(enum, accessor, options)
|
25
29
|
|
26
|
-
|
27
|
-
send "generate_enum_#{
|
30
|
+
EXTENSIONS.uniq.each do |extension|
|
31
|
+
send "generate_enum_#{extension}_extension_for", enum, accessor
|
28
32
|
end
|
29
33
|
|
30
34
|
enum
|
@@ -50,6 +54,20 @@ module SimpleEnum
|
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
57
|
+
def generate_additional_enum_methods_for(enum, accessor, options)
|
58
|
+
with_options = Array.wrap(options.fetch(:with, SimpleEnum.with))
|
59
|
+
scope_option, feature_options = with_options.partition { |option| option == :scope }
|
60
|
+
|
61
|
+
feature_options.each do |feature|
|
62
|
+
send "generate_enum_#{feature}_methods_for", enum, accessor
|
63
|
+
end
|
64
|
+
|
65
|
+
unless scope_option.empty?
|
66
|
+
pluralize_scopes = options.fetch(:pluralize_scopes, SimpleEnum.pluralize_scopes)
|
67
|
+
generate_enum_scope_methods_for(enum, accessor, pluralize_scopes)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
53
71
|
def generate_enum_dirty_methods_for(enum, accessor)
|
54
72
|
simple_enum_module.module_eval do
|
55
73
|
define_method("#{accessor}_changed?") { accessor.changed?(self) }
|
@@ -66,12 +84,26 @@ module SimpleEnum
|
|
66
84
|
end
|
67
85
|
end
|
68
86
|
|
69
|
-
def generate_enum_scope_methods_for(enum, accessor)
|
87
|
+
def generate_enum_scope_methods_for(enum, accessor, pluralize_scopes)
|
70
88
|
return unless respond_to?(:scope)
|
71
89
|
|
72
90
|
enum.each_pair do |key, value|
|
73
|
-
|
91
|
+
scope_key = pluralize_scopes ? key.pluralize : key
|
92
|
+
scope "#{accessor.prefix}#{scope_key}", -> { accessor.scope(self, value) }
|
74
93
|
end
|
75
94
|
end
|
76
95
|
end
|
96
|
+
|
97
|
+
# Public: Register a generator method and add module as part of
|
98
|
+
# SimpleEnum::Attribute. The generator method is called after all default
|
99
|
+
# generators have been created, this allows to override/change existing methods.
|
100
|
+
#
|
101
|
+
# name - The Symbol with the name of the extension
|
102
|
+
# mod - The Module implementing `generate_enum_{name}_extension_for` method
|
103
|
+
#
|
104
|
+
# Returns nothing
|
105
|
+
def self.register_generator(name, mod)
|
106
|
+
Attribute.send :include, mod
|
107
|
+
Attribute::EXTENSIONS << name.to_s
|
108
|
+
end
|
77
109
|
end
|
data/lib/simple_enum/enum.rb
CHANGED
@@ -25,6 +25,10 @@ module SimpleEnum
|
|
25
25
|
end
|
26
26
|
alias_method :[], :value
|
27
27
|
|
28
|
+
def fetch(key)
|
29
|
+
value(key) || raise("Key \"#{key}\" not found")
|
30
|
+
end
|
31
|
+
|
28
32
|
def each_pair(&block)
|
29
33
|
hash.each_pair(&block)
|
30
34
|
end
|
@@ -38,6 +42,15 @@ module SimpleEnum
|
|
38
42
|
hash.keys
|
39
43
|
end
|
40
44
|
|
45
|
+
def values
|
46
|
+
hash.values
|
47
|
+
end
|
48
|
+
|
49
|
+
def values_at(*keys)
|
50
|
+
keys = keys.map(&:to_s)
|
51
|
+
hash.values_at(*keys)
|
52
|
+
end
|
53
|
+
|
41
54
|
def to_s
|
42
55
|
name
|
43
56
|
end
|
data/lib/simple_enum/mongoid.rb
CHANGED
@@ -33,14 +33,16 @@ module SimpleEnum
|
|
33
33
|
# Wrap method chain to create mongoid field and additional
|
34
34
|
# column options
|
35
35
|
def as_enum(name, values, options = {})
|
36
|
-
source = options[:source].to_s.presence || "#{name}#{SimpleEnum.suffix}"
|
37
36
|
field_options = options.delete(:field)
|
37
|
+
enum = super
|
38
|
+
accessor = send("#{name.to_s.pluralize}_accessor")
|
39
|
+
|
38
40
|
unless field_options === false
|
39
41
|
field_options ||= SimpleEnum.field
|
40
|
-
field(source, field_options) if field_options
|
42
|
+
field(accessor.source, field_options) if field_options
|
41
43
|
end
|
42
44
|
|
43
|
-
|
45
|
+
enum
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
data/lib/simple_enum/version.rb
CHANGED
@@ -29,6 +29,22 @@ module SimpleEnum
|
|
29
29
|
}
|
30
30
|
end
|
31
31
|
|
32
|
+
# Helper method to return the translated value of an enum.
|
33
|
+
#
|
34
|
+
# translate_enum(user, :gender) # => "Frau"
|
35
|
+
#
|
36
|
+
# Has been aliased to `te` as a convenience method as well.
|
37
|
+
#
|
38
|
+
# record - The model instance holding the enum
|
39
|
+
# key - The Symbol with the name of the enum, i.e. same key as used in the
|
40
|
+
# `as_enum` call
|
41
|
+
#
|
42
|
+
# Returns String with translation of enum
|
43
|
+
def translate_enum(record, key)
|
44
|
+
record.class.human_enum_name(key, record.public_send(key))
|
45
|
+
end
|
46
|
+
alias_method :te, :translate_enum
|
47
|
+
|
32
48
|
private
|
33
49
|
|
34
50
|
def translate_enum_key(enum, key)
|
data/lib/simple_enum.rb
CHANGED
data/simple_enum.gemspec
CHANGED
@@ -25,6 +25,6 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
s.add_development_dependency 'rake', '>= 10.1.0'
|
27
27
|
s.add_development_dependency 'activerecord', '>= 4.0.0'
|
28
|
-
s.add_development_dependency 'mongoid', '>= 4.0.0
|
28
|
+
s.add_development_dependency 'mongoid', '>= 4.0.0'
|
29
29
|
s.add_development_dependency 'rspec', '~> 2.14'
|
30
30
|
end
|
@@ -19,6 +19,22 @@ describe SimpleEnum::Accessors do
|
|
19
19
|
end
|
20
20
|
end
|
21
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
|
+
|
22
38
|
context 'Accessor' do
|
23
39
|
subject { described_class::Accessor.new(:gender, enum) }
|
24
40
|
|
@@ -125,64 +141,134 @@ describe SimpleEnum::Accessors do
|
|
125
141
|
|
126
142
|
context '#selected?' do
|
127
143
|
it 'returns false when gender_cd is nil' do
|
128
|
-
expect(subject.selected?(object)).to
|
129
|
-
expect(subject.selected?(object, :male)).to
|
144
|
+
expect(subject.selected?(object)).to be_falsey
|
145
|
+
expect(subject.selected?(object, :male)).to be_falsey
|
130
146
|
end
|
131
147
|
|
132
148
|
it 'returns true when gender_cd is != nil' do
|
133
|
-
expect(subject.selected?(klass.new(0))).to
|
134
|
-
expect(subject.selected?(klass.new(1))).to
|
149
|
+
expect(subject.selected?(klass.new(0))).to be_truthy
|
150
|
+
expect(subject.selected?(klass.new(1))).to be_truthy
|
135
151
|
end
|
136
152
|
|
137
153
|
it 'returns true when gender_cd is 0 and :male is passed' do
|
138
|
-
expect(subject.selected?(klass.new(0), :male)).to
|
154
|
+
expect(subject.selected?(klass.new(0), :male)).to be_truthy
|
139
155
|
end
|
140
156
|
|
141
157
|
it 'returns false when gender_cd is 0 and :female is passed' do
|
142
|
-
expect(subject.selected?(klass.new(0), :female)).to
|
158
|
+
expect(subject.selected?(klass.new(0), :female)).to be_falsey
|
143
159
|
end
|
144
160
|
|
145
161
|
it 'returns false when gender_cd is 1 and :other is passed' do
|
146
|
-
expect(subject.selected?(klass.new(0), :other)).to
|
162
|
+
expect(subject.selected?(klass.new(0), :other)).to be_falsey
|
147
163
|
end
|
148
164
|
end
|
149
165
|
|
150
166
|
context '#changed?' do
|
151
167
|
it 'delegates to attribute_changed?' do
|
152
168
|
expect(object).to receive(:attribute_changed?).with('gender_cd') { true }
|
153
|
-
expect(subject.changed?(object)).to
|
169
|
+
expect(subject.changed?(object)).to be_truthy
|
154
170
|
end
|
155
171
|
end
|
156
172
|
|
157
|
-
context 'was' do
|
158
|
-
|
159
|
-
|
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 }
|
160
180
|
expect(subject.was(object)).to eq :female
|
161
181
|
end
|
162
182
|
end
|
163
183
|
end
|
164
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
|
+
|
165
251
|
context 'IgnoreAccessor' do
|
166
252
|
subject { described_class::IgnoreAccessor.new(:gender, enum) }
|
167
253
|
|
168
254
|
it 'sets gender_cd to 0 with symbol' do
|
169
|
-
expect(subject.write(object, :male)).to_not
|
255
|
+
expect(subject.write(object, :male)).to_not be_falsey
|
170
256
|
expect(object.gender_cd).to eq 0
|
171
257
|
end
|
172
258
|
|
173
259
|
it 'sets gender_cd to 1 via value (1)' do
|
174
|
-
expect(subject.write(object, 1)).to_not
|
260
|
+
expect(subject.write(object, 1)).to_not be_falsey
|
175
261
|
expect(object.gender_cd).to eq 1
|
176
262
|
end
|
177
263
|
|
178
264
|
it 'sets gender_cd to nil' do
|
179
|
-
expect(subject.write(object, nil)).to
|
265
|
+
expect(subject.write(object, nil)).to be_falsey
|
180
266
|
expect(object.gender_cd).to be_nil
|
181
267
|
end
|
182
268
|
|
183
269
|
it 'keeps existing value when unknown value is passed' do
|
184
270
|
object.gender_cd = 1
|
185
|
-
expect(subject.write(object, :other)).to
|
271
|
+
expect(subject.write(object, :other)).to be_falsey
|
186
272
|
expect(object.gender_cd).to eq 1
|
187
273
|
end
|
188
274
|
end
|
@@ -10,6 +10,37 @@ describe SimpleEnum::Attribute do
|
|
10
10
|
end
|
11
11
|
end
|
12
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
|
+
|
13
44
|
context 'generate_enum_class_accessors_for' do
|
14
45
|
context '.genders' do
|
15
46
|
subject { klass.genders }
|
@@ -48,7 +79,7 @@ describe SimpleEnum::Attribute do
|
|
48
79
|
context '#gender?' do
|
49
80
|
it 'delegates to accessor' do
|
50
81
|
expect(accessor).to receive(:selected?).with(subject, nil) { nil }
|
51
|
-
expect(subject.gender?).to
|
82
|
+
expect(subject.gender?).to be_falsey
|
52
83
|
end
|
53
84
|
end
|
54
85
|
end
|
@@ -70,7 +101,7 @@ describe SimpleEnum::Attribute do
|
|
70
101
|
|
71
102
|
it 'delegates #gender_changed? to accessor' do
|
72
103
|
expect(accessor).to receive(:changed?).with(subject) { true }
|
73
|
-
expect(subject.gender_changed?).to
|
104
|
+
expect(subject.gender_changed?).to be_truthy
|
74
105
|
end
|
75
106
|
|
76
107
|
it 'delegates #gender_was to accesso' do
|
@@ -99,17 +130,17 @@ describe SimpleEnum::Attribute do
|
|
99
130
|
|
100
131
|
it 'delegates #gender? to accessor' do
|
101
132
|
expect(accessor).to receive(:selected?).with(subject, nil) { :female }
|
102
|
-
expect(subject.gender?).to
|
133
|
+
expect(subject.gender?).to be_truthy
|
103
134
|
end
|
104
135
|
|
105
136
|
it 'delegates #male? to accessor' do
|
106
137
|
expect(accessor).to receive(:selected?).with(subject, 'male') { true }
|
107
|
-
expect(subject.male?).to
|
138
|
+
expect(subject.male?).to be_truthy
|
108
139
|
end
|
109
140
|
|
110
141
|
it 'delegates #female? to accessor' do
|
111
142
|
expect(accessor).to receive(:selected?).with(subject, 'female') { false }
|
112
|
-
expect(subject.female?).to
|
143
|
+
expect(subject.female?).to be_falsey
|
113
144
|
end
|
114
145
|
|
115
146
|
it 'delegates #male! to accessor' do
|
@@ -129,17 +160,17 @@ describe SimpleEnum::Attribute do
|
|
129
160
|
|
130
161
|
it 'delegates #gender? to accessor' do
|
131
162
|
expect(accessor).to receive(:selected?).with(subject, nil) { :female }
|
132
|
-
expect(subject.gender?).to
|
163
|
+
expect(subject.gender?).to be_truthy
|
133
164
|
end
|
134
165
|
|
135
166
|
it 'delegates #gender_male? to accessor' do
|
136
167
|
expect(accessor).to receive(:selected?).with(subject, 'male') { true }
|
137
|
-
expect(subject.gender_male?).to
|
168
|
+
expect(subject.gender_male?).to be_truthy
|
138
169
|
end
|
139
170
|
|
140
171
|
it 'delegates #gender_female? to accessor' do
|
141
172
|
expect(accessor).to receive(:selected?).with(subject, 'female') { false }
|
142
|
-
expect(subject.gender_female?).to
|
173
|
+
expect(subject.gender_female?).to be_falsey
|
143
174
|
end
|
144
175
|
|
145
176
|
it 'delegates #gender_male! to accessor' do
|
@@ -159,25 +190,23 @@ describe SimpleEnum::Attribute do
|
|
159
190
|
as_enum :gender, [:male, :female], with: [:scope]
|
160
191
|
}
|
161
192
|
|
162
|
-
|
163
|
-
it 'returns an ActiveRecord::Relation' do
|
164
|
-
expect(subject).to be_a(ActiveRecord::Relation)
|
165
|
-
end
|
193
|
+
let(:accessor) { klass.genders_accessor }
|
166
194
|
|
167
|
-
|
168
|
-
|
169
|
-
expect(
|
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
|
170
199
|
end
|
171
200
|
end
|
172
201
|
|
173
202
|
context '.males' do
|
174
203
|
subject { klass.males }
|
175
|
-
it_behaves_like '
|
204
|
+
it_behaves_like 'delegates to accessor#scope', 0
|
176
205
|
end
|
177
206
|
|
178
207
|
context '.females' do
|
179
208
|
subject { klass.females }
|
180
|
-
it_behaves_like '
|
209
|
+
it_behaves_like 'delegates to accessor#scope', 1
|
181
210
|
end
|
182
211
|
|
183
212
|
context 'with prefix' do
|
@@ -187,12 +216,44 @@ describe SimpleEnum::Attribute do
|
|
187
216
|
|
188
217
|
context '.gender_males' do
|
189
218
|
subject { klass.gender_males }
|
190
|
-
it_behaves_like '
|
219
|
+
it_behaves_like 'delegates to accessor#scope', 0
|
191
220
|
end
|
192
221
|
|
193
222
|
context '.gender_females' do
|
194
223
|
subject { klass.gender_females }
|
195
|
-
it_behaves_like '
|
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
|
196
257
|
end
|
197
258
|
end
|
198
259
|
|
@@ -38,6 +38,12 @@ describe SimpleEnum::Enum do
|
|
38
38
|
end
|
39
39
|
end
|
40
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
|
+
|
41
47
|
context '#each_pair (aliased to #each)' do
|
42
48
|
it 'yields twice with #each_pair' do
|
43
49
|
expect { |b| subject.each_pair(&b) }.to yield_control.exactly(2).times
|
@@ -70,6 +76,24 @@ describe SimpleEnum::Enum do
|
|
70
76
|
end
|
71
77
|
end
|
72
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
|
+
|
73
97
|
context '#key' do
|
74
98
|
it 'returns symbolized key for supplied value' do
|
75
99
|
expect(subject.key(0)).to eq :male
|
@@ -83,20 +107,30 @@ describe SimpleEnum::Enum do
|
|
83
107
|
|
84
108
|
context '#include?' do
|
85
109
|
it 'returns true by string' do
|
86
|
-
expect(subject.include?('male')).to
|
110
|
+
expect(subject.include?('male')).to be_truthy
|
87
111
|
end
|
88
112
|
|
89
113
|
it 'returns true by symbol' do
|
90
|
-
expect(subject.include?(:female)).to
|
114
|
+
expect(subject.include?(:female)).to be_truthy
|
91
115
|
end
|
92
116
|
|
93
117
|
it 'returns true by checking actual value' do
|
94
|
-
expect(subject.include?(1)).to
|
118
|
+
expect(subject.include?(1)).to be_truthy
|
95
119
|
end
|
96
120
|
|
97
121
|
it 'returns false when neither in keys nor values' do
|
98
|
-
expect(subject.include?(:other)).to
|
99
|
-
expect(subject.include?(2)).to
|
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]
|
100
134
|
end
|
101
135
|
end
|
102
136
|
end
|
@@ -13,6 +13,10 @@ describe SimpleEnum::Translation do
|
|
13
13
|
it 'translates :female to "Mrs."' do
|
14
14
|
expect(subject.human_enum_name(:gender, :female)).to eq 'Mrs.'
|
15
15
|
end
|
16
|
+
|
17
|
+
it 'returns empty string when key is missing' do
|
18
|
+
expect(subject.human_enum_name(:gender, nil)).to eq ''
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
context '{i18n_scope}.enums.{i18n_key}.gender.{key}' do
|
@@ -59,4 +59,13 @@ describe SimpleEnum::ViewHelpers, i18n: true do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
+
|
63
|
+
context '#translate_enum' do
|
64
|
+
let(:fake_object) { klass.new }
|
65
|
+
it "translates with object scope" do
|
66
|
+
fake_object.gender = :male
|
67
|
+
expect(klass).to receive(:human_enum_name).with(:gender, :male) { "Mr." }
|
68
|
+
expect(helper.translate_enum(fake_object, :gender)).to eq "Mr."
|
69
|
+
end
|
70
|
+
end
|
62
71
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module I18nSupport
|
2
2
|
def self.included(base)
|
3
3
|
base.let!(:i18n_previous_backend) { I18n.backend }
|
4
|
-
base.let(:i18n_backend) { I18n::Backend::
|
4
|
+
base.let(:i18n_backend) { I18n::Backend::Simple.new() }
|
5
5
|
base.before { I18n.backend = i18n_backend }
|
6
6
|
base.after { I18n.backend = i18n_previous_backend }
|
7
7
|
end
|
@@ -1,20 +1,46 @@
|
|
1
1
|
require 'mongoid'
|
2
2
|
|
3
|
+
# Hack to disable auto-retries for Mongo::Client - unless running
|
4
|
+
# on Travis CI
|
5
|
+
if ENV['CI'] && Mongoid.respond_to?(:default_client)
|
6
|
+
require 'mongo'
|
7
|
+
|
8
|
+
module Mongo
|
9
|
+
class Cluster
|
10
|
+
def scan!
|
11
|
+
raise ArgumentError, 'no retries please.'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
module MongoidSupport
|
4
18
|
def self.connection
|
5
|
-
@
|
6
|
-
Mongoid.configure
|
7
|
-
|
19
|
+
@connection_config ||= begin
|
20
|
+
Mongoid.configure do |config|
|
21
|
+
config.connect_to("simple_enum_mongoid_test", max_retries: ENV['CI'] ? 5 : 0)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Disable client errors
|
25
|
+
Moped.logger.level = Logger::ERROR if defined?(Moped)
|
26
|
+
Mongo::Logger.logger.level = Logger::ERROR if defined?(Mongo)
|
27
|
+
|
28
|
+
# Return instance
|
29
|
+
return Mongoid.default_client if Mongoid.respond_to?(:default_client)
|
30
|
+
Mongoid.default_session
|
8
31
|
end
|
9
|
-
Mongoid.default_session
|
10
32
|
end
|
11
33
|
|
12
34
|
def self.included(base)
|
13
35
|
base.before {
|
14
36
|
begin
|
15
|
-
MongoidSupport.connection.
|
16
|
-
rescue
|
17
|
-
|
37
|
+
MongoidSupport.connection.database_names
|
38
|
+
rescue => e
|
39
|
+
if ENV['CI']
|
40
|
+
raise e
|
41
|
+
else
|
42
|
+
skip "Start MongoDB server to run Mongoid integration tests..."
|
43
|
+
end
|
18
44
|
end
|
19
45
|
}
|
20
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lukas Westermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 4.0.0
|
61
|
+
version: 4.0.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 4.0.0
|
68
|
+
version: 4.0.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
138
|
version: 2.0.0
|
139
139
|
requirements: []
|
140
140
|
rubyforge_project:
|
141
|
-
rubygems_version: 2.
|
141
|
+
rubygems_version: 2.6.13
|
142
142
|
signing_key:
|
143
143
|
specification_version: 4
|
144
144
|
summary: Simple enum-like field support for models.
|