simple_enum 2.0.0 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/simple_enum.svg)](https://badge.fury.io/rb/simple_enum)
|
4
5
|
[![Build Status](https://travis-ci.org/lwe/simple_enum.svg)](https://travis-ci.org/lwe/simple_enum)
|
5
|
-
[![Code Climate](https://codeclimate.com/github/lwe/simple_enum.
|
6
|
+
[![Code Climate](https://codeclimate.com/github/lwe/simple_enum.svg)](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.
|