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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2ccef9004864a8144f12e09b8f9d3b7337f2a6e
4
- data.tar.gz: 42a62edab3dbf1af37c8368f4eeecfb5d0c5ab5f
3
+ metadata.gz: ead9e5d2a63ed29727c934fa36cf37a544dacd65
4
+ data.tar.gz: 89da3f9fa8ee6e7ef19f028bed68167d8e592f55
5
5
  SHA512:
6
- metadata.gz: 1ad263fa8e8705c4534a11f278db11cf564b6ce1371b3f50883d4e4dd41a583492e2e807410d7da63e794d3b110a991d45d2857fb6f8369367d529db879f78c1
7
- data.tar.gz: 913a6473142147a01aecec53ac5ce3ad6b6e0a96aac61898384536383df16b8118a4aa512f1ff8f590866efd9223db066c43c2858d3de955eca704011e124f67
6
+ metadata.gz: 834dd3a7c5e92d44c0317ac88356af38a56fdc0581dd4b4101583dbb494f0fa1d027e88f2bd1d9d134783bab08171ff998d604d78db5ce3588cec24c301f4b1e
7
+ data.tar.gz: a4947957c71ddeb731981403288daea009f8e6b565657cf04a140de9201cf507e2f0c81490981b2d481f903035ac608572c89e3b62b8b4499d671775f4ffa6a9
data/.gitignore CHANGED
@@ -6,4 +6,5 @@ pkg
6
6
  .*.sw?
7
7
  tmp
8
8
  Gemfile.lock
9
+ gemfiles/*.lock
9
10
  :memory*
data/Gemfile CHANGED
@@ -1,5 +1,8 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem 'activesupport', '~> 5.0.0'
4
+ gem 'activerecord', '~> 5.0.0'
5
+
3
6
  gemspec
4
7
 
5
8
  # some development deps
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Lukas Westermann (Zurich, Switzerland)
1
+ Copyright (c) 2015 Lukas Westermann (Zurich, Switzerland)
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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.png)](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.0.0.rc1' , require: 'simple_enum/mongoid'
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 # => #<SimpleEnum::Enum:0x0....>
100
- User.genders[:male] # => 0
101
- User.females # => #<ActiveRecord::Relation:0x0.....> (WHERE gender_cd = 1)
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, beaware that any
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 = [:accessor, :scope]
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], :prefix => true
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
- * @dmitry - bugfixes and other improvements
235
- * @tarsolya - implemented all the ruby 1.9 and rails 3 goodness!
236
- * @dbalatero - rails 2.3.5 bugfix & validator fixes
237
- * @johnthethird - feature for <tt>_for_select</tt> to return the values
238
- * @sinsiliux - ruby 1.9 fixes and removed AR dependency
239
- * @sled - mongoid support
240
- * @abrom - <tt>find_by_...</tt> method
241
- * @mhuggins - translations fixes
242
- * @patbenatar - for helping move towards 2.0 (scopes et all)
243
- * and all others: https://github.com/lwe/simple_enum/graphs/contributors thanks
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-2014 by Lukas Westermann, Licensed under MIT Licence (see LICENSE file)
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 rspec test suite'
11
- task :spec do
12
- sh 'bundle exec rspec spec/'
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?(source)
32
+ object.send(:attribute_changed?, source)
33
33
  end
34
34
 
35
35
  def was(object)
36
- enum.key(object.attribute_was(source))
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
- Array.wrap(options.fetch(:with, SimpleEnum.with)).each do |feature|
27
- send "generate_enum_#{feature}_methods_for", enum, accessor
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
- scope "#{accessor.prefix}#{key.pluralize}", -> { where(accessor.source => value) }
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
@@ -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
@@ -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
- super
45
+ enum
44
46
  end
45
47
  end
46
48
  end
@@ -3,6 +3,8 @@ require 'i18n'
3
3
  module SimpleEnum
4
4
  module Translation
5
5
  def human_enum_name(enum, key, options = {})
6
+ return '' unless key.present?
7
+
6
8
  defaults = lookup_ancestors.map do |klass|
7
9
  :"#{self.i18n_scope}.enums.#{klass.model_name.i18n_key}.#{enum}.#{key}"
8
10
  end
@@ -1,5 +1,5 @@
1
1
  module SimpleEnum
2
2
 
3
3
  # The current `SimpleEnum` version.
4
- VERSION = "2.0.0"
4
+ VERSION = "2.3.2"
5
5
  end
@@ -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
@@ -33,6 +33,9 @@ module SimpleEnum
33
33
  mattr_accessor :field
34
34
  @@field = {}
35
35
 
36
+ mattr_accessor :pluralize_scopes
37
+ @@pluralize_scopes = true
38
+
36
39
  def self.configure
37
40
  yield(self)
38
41
  end
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.beta1'
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 be_false
129
- expect(subject.selected?(object, :male)).to be_false
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 be_true
134
- expect(subject.selected?(klass.new(1))).to be_true
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 be_true
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 be_false
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 be_false
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 be_true
169
+ expect(subject.changed?(object)).to be_truthy
154
170
  end
155
171
  end
156
172
 
157
- context 'was' do
158
- it 'delegates to attribute_was and resolves symbol' do
159
- expect(object).to receive(:attribute_was).with('gender_cd') { 1 }
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 be_false
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 be_false
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 be_false
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 be_false
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 be_false
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 be_true
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 be_true
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 be_true
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 be_false
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 be_true
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 be_true
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 be_false
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
- shared_examples_for 'returning a relation' do |value|
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
- it "queries for gender_cd = #{value}" do
168
- values_hash = { "gender_cd" => value }
169
- expect(subject.where_values_hash).to eq values_hash
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 'returning a relation', 0
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 'returning a relation', 1
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 'returning a relation', 0
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 'returning a relation', 1
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 be_true
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 be_true
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 be_true
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 be_false
99
- expect(subject.include?(2)).to be_false
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
@@ -6,8 +6,8 @@ require 'active_record'
6
6
  require 'mongoid'
7
7
 
8
8
  if ENV['CODECLIMATE_REPO_TOKEN']
9
- require "codeclimate-test-reporter"
10
- CodeClimate::TestReporter.start
9
+ require 'simplecov'
10
+ SimpleCov.start
11
11
  end
12
12
 
13
13
  require 'simple_enum'
@@ -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::KeyValue.new({}) }
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
- @connection ||= begin
6
- Mongoid.configure.connect_to("simple_enum_mongoid_test")
7
- Mongoid.default_session.options[:max_retries] = 0
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.collection_names
16
- rescue Moped::Errors::ConnectionFailure
17
- pending "Start MongoDB server to run Mongoid integration tests..."
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.0.0
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: 2014-07-02 00:00:00.000000000 Z
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.beta1
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.beta1
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.2.0
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.