enumerize 0.6.1 → 0.7.0
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.
- data/.travis.yml +0 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile +3 -1
- data/Gemfile.rails4 +4 -2
- data/README.md +45 -2
- data/Rakefile +6 -0
- data/enumerize.gemspec +3 -3
- data/lib/enumerize.rb +5 -0
- data/lib/enumerize/activerecord.rb +30 -12
- data/lib/enumerize/attribute.rb +13 -1
- data/lib/enumerize/attribute_map.rb +2 -0
- data/lib/enumerize/base.rb +19 -11
- data/lib/enumerize/integrations/rspec.rb +17 -0
- data/lib/enumerize/integrations/rspec/matcher.rb +76 -0
- data/lib/enumerize/predicatable.rb +30 -0
- data/lib/enumerize/set.rb +9 -0
- data/lib/enumerize/value.rb +8 -27
- data/lib/enumerize/version.rb +1 -1
- data/test/activerecord_test.rb +22 -0
- data/test/base_test.rb +21 -1
- data/test/formtastic_test.rb +1 -0
- data/test/module_attributes_test.rb +21 -0
- data/test/mongo_mapper_test.rb +68 -0
- data/test/mongoid_test.rb +1 -1
- data/test/multiple_test.rb +5 -0
- data/test/predicates_test.rb +13 -0
- data/test/rspec_matcher_test.rb +53 -0
- data/test/rspec_spec.rb +13 -0
- data/test/set_test.rb +38 -0
- data/test/simple_form_test.rb +1 -0
- data/test/test_helper.rb +0 -14
- data/test/value_test.rb +28 -0
- metadata +12 -5
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.7.0 (August 21, 2013) ##
|
2
|
+
|
3
|
+
### enhancements
|
4
|
+
* Give priority to model specific translation definition. See example [here](https://github.com/brainspec/enumerize/pull/96) (by [@labocho](https://github.com/labocho))
|
5
|
+
* Allow lambda in default value (by [@adie](https://github.com/adie))
|
6
|
+
* Add predicate methods to the multiple attributes (by [@nashby](https://github.com/nashby))
|
7
|
+
* Add RSpec matcher (by [@nashby](https://github.com/nashby))
|
8
|
+
* Add `*_value` method that returns actual value of the enumerized attribute (useful for attributes with custom values)
|
9
|
+
(by [@tkyowa](https://github.com/tkyowa))
|
10
|
+
|
11
|
+
### bug fix
|
12
|
+
* Make validation work when `write_attribute` is using for setting enumerized values (by [@nashby](https://github.com/nashby))
|
13
|
+
* Validates enumerized values when enumeration is included via module
|
14
|
+
(by [@nashby](https://github.com/nashby)) and (by [@lest](https://github.com/lest))
|
15
|
+
|
1
16
|
## 0.6.1 (May 20, 2013) ##
|
2
17
|
|
3
18
|
### bug fix
|
data/Gemfile
CHANGED
@@ -4,11 +4,13 @@ gemspec
|
|
4
4
|
|
5
5
|
gem 'rake'
|
6
6
|
gem 'minitest', '~> 4.1'
|
7
|
+
gem 'rspec', :require => false
|
7
8
|
|
8
|
-
gem '
|
9
|
+
gem 'rails', '~> 3.2.0', :require => false
|
9
10
|
gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
|
10
11
|
gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
|
11
12
|
|
12
13
|
gem 'mongoid'
|
14
|
+
gem 'mongo_mapper'
|
13
15
|
gem 'simple_form'
|
14
16
|
gem 'formtastic'
|
data/Gemfile.rails4
CHANGED
@@ -4,11 +4,13 @@ gemspec
|
|
4
4
|
|
5
5
|
gem 'rake'
|
6
6
|
gem 'minitest', '~> 4.1'
|
7
|
+
gem 'rspec', :require => false
|
7
8
|
|
8
|
-
gem '
|
9
|
+
gem 'rails', '4.0.0', :require => false
|
9
10
|
gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
|
10
11
|
gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
|
11
12
|
|
12
13
|
gem 'mongoid', github: 'mongoid/mongoid'
|
13
|
-
gem '
|
14
|
+
gem 'mongo_mapper', github: 'jnunemaker/mongomapper'
|
15
|
+
gem 'simple_form', github: 'plataformatec/simple_form'
|
14
16
|
gem 'formtastic', github: 'justinfrench/formtastic'
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Enumerize [](http://travis-ci.org/brainspec/enumerize) [](https://gemnasium.com/brainspec/enumerize)
|
2
2
|
|
3
|
-
Enumerated attributes with I18n and ActiveRecord/Mongoid support
|
3
|
+
Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -34,7 +34,7 @@ ActiveRecord:
|
|
34
34
|
class User < ActiveRecord::Base
|
35
35
|
extend Enumerize
|
36
36
|
|
37
|
-
enumerize :sex, in: [:male, :female]
|
37
|
+
enumerize :sex, in: [:male, :female], default: lambda { |user| SexIdentifier.sex_for_name(user.name).to_sym }
|
38
38
|
|
39
39
|
enumerize :role, in: [:user, :admin], default: :user
|
40
40
|
end
|
@@ -52,6 +52,18 @@ class User
|
|
52
52
|
end
|
53
53
|
```
|
54
54
|
|
55
|
+
MongoMapper:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class User
|
59
|
+
include MongoMapper::Document
|
60
|
+
extend Enumerize
|
61
|
+
|
62
|
+
key :role
|
63
|
+
enumerize :role, in: [:user, :admin], default: :user
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
55
67
|
I18n:
|
56
68
|
|
57
69
|
```ruby
|
@@ -73,6 +85,15 @@ en:
|
|
73
85
|
female: "Female"
|
74
86
|
```
|
75
87
|
|
88
|
+
Note that if you want to use I18n feature with plain Ruby object don't forget to extend it with `ActiveModel::Naming`:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class User
|
92
|
+
extend Enumerize
|
93
|
+
extend ActiveModel::Naming
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
76
97
|
get attribute value:
|
77
98
|
|
78
99
|
```ruby
|
@@ -162,6 +183,11 @@ class User < ActiveRecord::Base
|
|
162
183
|
|
163
184
|
enumerize :role, in: {:user => 1, :admin => 2}
|
164
185
|
end
|
186
|
+
|
187
|
+
user = User.new
|
188
|
+
user.role = :user
|
189
|
+
user.role #=> 'user'
|
190
|
+
user.role_value #=> 1
|
165
191
|
```
|
166
192
|
|
167
193
|
ActiveRecord scopes:
|
@@ -244,6 +270,23 @@ and if you want it as radio buttons:
|
|
244
270
|
<% end %>
|
245
271
|
```
|
246
272
|
|
273
|
+
### RSpec
|
274
|
+
|
275
|
+
Also you can use builtin RSpec matcher:
|
276
|
+
|
277
|
+
```ruby
|
278
|
+
class User
|
279
|
+
extend Enumerize
|
280
|
+
|
281
|
+
enumerize :sex, in: [:male, :female], default: :male
|
282
|
+
end
|
283
|
+
|
284
|
+
describe User do
|
285
|
+
it { should enumerize(:sex).in(:male, :female) }
|
286
|
+
it { should enumerize(:sex).in(:male, :female).with_default(:male) }
|
287
|
+
end
|
288
|
+
```
|
289
|
+
|
247
290
|
### Other Integrations
|
248
291
|
|
249
292
|
Enumerize integrates with the following automatically:
|
data/Rakefile
CHANGED
@@ -2,10 +2,16 @@
|
|
2
2
|
require "bundler/gem_tasks"
|
3
3
|
|
4
4
|
require 'rake/testtask'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
5
7
|
Rake::TestTask.new do |t|
|
6
8
|
t.libs << 'test'
|
7
9
|
t.pattern = 'test/*_test.rb'
|
8
10
|
t.verbose = true
|
9
11
|
end
|
10
12
|
|
13
|
+
RSpec::Core::RakeTask.new('default') do |t|
|
14
|
+
t.pattern = FileList['test/rspec_spec.rb']
|
15
|
+
end
|
16
|
+
|
11
17
|
task :default => :test
|
data/enumerize.gemspec
CHANGED
@@ -4,8 +4,8 @@ require File.expand_path('../lib/enumerize/version', __FILE__)
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Sergey Nartimov"]
|
6
6
|
gem.email = "team@brainspec.com"
|
7
|
-
gem.description = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid support}
|
8
|
-
gem.summary = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid support}
|
7
|
+
gem.description = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
|
8
|
+
gem.summary = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
|
9
9
|
gem.homepage = "https://github.com/brainspec/enumerize"
|
10
10
|
|
11
11
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "enumerize"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Enumerize::VERSION
|
17
|
-
|
17
|
+
|
18
18
|
gem.required_ruby_version = '>= 1.9.3'
|
19
19
|
|
20
20
|
gem.add_dependency('activesupport', '>= 3.2')
|
data/lib/enumerize.rb
CHANGED
@@ -10,6 +10,7 @@ module Enumerize
|
|
10
10
|
autoload :Module, 'enumerize/module'
|
11
11
|
autoload :ActiveRecord, 'enumerize/activerecord'
|
12
12
|
autoload :Predicates, 'enumerize/predicates'
|
13
|
+
autoload :Predicatable, 'enumerize/predicatable'
|
13
14
|
autoload :ModuleAttributes, 'enumerize/module_attributes'
|
14
15
|
|
15
16
|
def self.included(base)
|
@@ -47,4 +48,8 @@ module Enumerize
|
|
47
48
|
require 'enumerize/hooks/formtastic'
|
48
49
|
rescue LoadError
|
49
50
|
end
|
51
|
+
|
52
|
+
if defined?(::RSpec)
|
53
|
+
require 'enumerize/integrations/rspec'
|
54
|
+
end
|
50
55
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
1
|
module Enumerize
|
4
2
|
module ActiveRecord
|
5
3
|
def enumerize(name, options={})
|
@@ -8,23 +6,43 @@ module Enumerize
|
|
8
6
|
if options[:scope]
|
9
7
|
_enumerize_module.dependent_eval do
|
10
8
|
if defined?(::ActiveRecord::Base) && self < ::ActiveRecord::Base
|
11
|
-
|
12
|
-
define_singleton_method scope_name do |*values|
|
13
|
-
values = values.map { |value| enumerized_attributes[name].find_value(value).value }
|
14
|
-
values = values.first if values.size == 1
|
9
|
+
_define_scope_methods!(name, options)
|
15
10
|
|
16
|
-
|
17
|
-
|
11
|
+
class_eval do
|
12
|
+
# https://github.com/brainspec/enumerize/issues/74
|
13
|
+
def write_attribute(attr_name, value)
|
14
|
+
_enumerized_values_for_validation[attr_name] = value
|
18
15
|
|
19
|
-
|
20
|
-
define_singleton_method "without_#{name}" do |*values|
|
21
|
-
values = values.map { |value| enumerized_attributes[name].find_value(value).value }
|
22
|
-
where(arel_table[name].not_in(values))
|
16
|
+
super
|
23
17
|
end
|
18
|
+
|
19
|
+
# Since Rails use `allocate` method on models and initializes them with `init_with` method.
|
20
|
+
# This way `initialize` method is not being called, but `after_initialize` callback always gets triggered.
|
21
|
+
after_initialize :_set_default_value_for_enumerized_attributes
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def _define_scope_methods!(name, options)
|
31
|
+
scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
|
32
|
+
|
33
|
+
define_singleton_method scope_name do |*values|
|
34
|
+
values = values.map { |value| enumerized_attributes[name].find_value(value).value }
|
35
|
+
values = values.first if values.size == 1
|
36
|
+
|
37
|
+
where(name => values)
|
38
|
+
end
|
39
|
+
|
40
|
+
if options[:scope] == true
|
41
|
+
define_singleton_method "without_#{name}" do |*values|
|
42
|
+
values = values.map { |value| enumerized_attributes[name].find_value(value).value }
|
43
|
+
where(arel_table[name].not_in(values))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
29
47
|
end
|
30
48
|
end
|
data/lib/enumerize/attribute.rb
CHANGED
@@ -14,11 +14,19 @@ module Enumerize
|
|
14
14
|
@value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
|
15
15
|
|
16
16
|
if options[:default]
|
17
|
-
@default_value =
|
17
|
+
@default_value = find_default_value(options[:default])
|
18
18
|
raise ArgumentError, 'invalid default value' unless @default_value
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def find_default_value(value)
|
23
|
+
if value.respond_to?(:call)
|
24
|
+
value
|
25
|
+
else
|
26
|
+
find_value(value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
22
30
|
def find_value(value)
|
23
31
|
@value_hash[value.to_s] unless value.nil?
|
24
32
|
end
|
@@ -82,6 +90,10 @@ module Enumerize
|
|
82
90
|
def #{name}_text
|
83
91
|
self.#{name} && self.#{name}.text
|
84
92
|
end
|
93
|
+
|
94
|
+
def #{name}_value
|
95
|
+
self.#{name} && self.#{name}.value
|
96
|
+
end
|
85
97
|
RUBY
|
86
98
|
end
|
87
99
|
end
|
data/lib/enumerize/base.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
1
|
module Enumerize
|
4
2
|
module Base
|
5
|
-
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
validate :_validate_enumerized_attributes
|
6
|
+
if base.respond_to?(:validate)
|
7
|
+
base.validate :_validate_enumerized_attributes
|
10
8
|
end
|
11
9
|
end
|
12
10
|
|
@@ -48,11 +46,7 @@ module Enumerize
|
|
48
46
|
|
49
47
|
def initialize(*)
|
50
48
|
super
|
51
|
-
|
52
|
-
if !public_send(attr.name) && !_enumerized_values_for_validation.key?(attr.name)
|
53
|
-
public_send("#{attr.name}=", attr.default_value)
|
54
|
-
end
|
55
|
-
end
|
49
|
+
_set_default_value_for_enumerized_attributes
|
56
50
|
end
|
57
51
|
|
58
52
|
def read_attribute_for_validation(key)
|
@@ -81,5 +75,19 @@ module Enumerize
|
|
81
75
|
end
|
82
76
|
end
|
83
77
|
end
|
78
|
+
|
79
|
+
def _set_default_value_for_enumerized_attributes
|
80
|
+
self.class.enumerized_attributes.each do |attr|
|
81
|
+
if !public_send(attr.name) && !_enumerized_values_for_validation.key?(attr.name)
|
82
|
+
value = attr.default_value
|
83
|
+
|
84
|
+
if value.respond_to?(:call)
|
85
|
+
value = value.arity == 0 ? value.call : value.call(self)
|
86
|
+
end
|
87
|
+
|
88
|
+
public_send("#{attr.name}=", value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
84
92
|
end
|
85
93
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'enumerize/integrations/rspec/matcher'
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module Integrations
|
5
|
+
module RSpec
|
6
|
+
def enumerize(attr)
|
7
|
+
::Enumerize::Integrations::RSpec::Matcher.new(attr)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module RSpec
|
14
|
+
module Matchers
|
15
|
+
include Enumerize::Integrations::RSpec
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Enumerize
|
2
|
+
module Integrations
|
3
|
+
module RSpec
|
4
|
+
class Matcher
|
5
|
+
attr_accessor :attr, :values, :subject, :default
|
6
|
+
|
7
|
+
def initialize(attr)
|
8
|
+
self.attr = attr
|
9
|
+
end
|
10
|
+
|
11
|
+
def in(*values)
|
12
|
+
self.values = values.map(&:to_s).sort
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def with_default(default)
|
17
|
+
self.default = default.to_s
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def failure_message
|
22
|
+
message = " expected :#{attr} to allow value#{values.size == 1 ? nil : 's'}: #{quote_values(values)},"
|
23
|
+
message += " but it allows #{quote_values(enumerized_values)} instead"
|
24
|
+
|
25
|
+
if default
|
26
|
+
message = " expected :#{attr} to have #{default.inspect} as default value,"
|
27
|
+
message += " but it sets #{enumerized_default.inspect} instead"
|
28
|
+
end
|
29
|
+
|
30
|
+
message
|
31
|
+
end
|
32
|
+
|
33
|
+
def description
|
34
|
+
description = "enumerize :#{attr} in: #{quote_values(values)}"
|
35
|
+
description += " with #{default.inspect} as default value" if default
|
36
|
+
end
|
37
|
+
|
38
|
+
def matches?(subject)
|
39
|
+
self.subject = subject
|
40
|
+
matches = true
|
41
|
+
|
42
|
+
matches &= matches_attributes?
|
43
|
+
matches &= matches_default_value? if default
|
44
|
+
|
45
|
+
matches
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def matches_attributes?
|
51
|
+
values == enumerized_values
|
52
|
+
end
|
53
|
+
|
54
|
+
def matches_default_value?
|
55
|
+
default == enumerized_default
|
56
|
+
end
|
57
|
+
|
58
|
+
def enumerized_values
|
59
|
+
@enumerized_values ||= attributes[attr.to_s].values.sort
|
60
|
+
end
|
61
|
+
|
62
|
+
def enumerized_default
|
63
|
+
@enumerized_default ||= attributes[attr.to_s].default_value
|
64
|
+
end
|
65
|
+
|
66
|
+
def attributes
|
67
|
+
subject.class.enumerized_attributes.attributes
|
68
|
+
end
|
69
|
+
|
70
|
+
def quote_values(values)
|
71
|
+
values.map(&:inspect).join(', ')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Enumerize
|
2
|
+
module Predicatable
|
3
|
+
def method_missing(method, *args, &block)
|
4
|
+
if boolean_method?(method)
|
5
|
+
define_query_methods
|
6
|
+
send(method, *args, &block)
|
7
|
+
else
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to_missing?(method, include_private=false)
|
13
|
+
boolean_method?(method)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def define_query_methods
|
19
|
+
@attr.values.each do |value|
|
20
|
+
unless singleton_methods.include?(:"#{value}?")
|
21
|
+
define_query_method(value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def boolean_method?(method)
|
27
|
+
method[-1] == '?' && @attr.values.include?(method[0..-2])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/enumerize/set.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Enumerize
|
2
2
|
class Set
|
3
3
|
include Enumerable
|
4
|
+
include Predicatable
|
4
5
|
|
5
6
|
attr_reader :values
|
6
7
|
|
@@ -53,6 +54,14 @@ module Enumerize
|
|
53
54
|
|
54
55
|
private
|
55
56
|
|
57
|
+
def define_query_method(value)
|
58
|
+
singleton_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
59
|
+
def #{value}?
|
60
|
+
include?("#{value}")
|
61
|
+
end
|
62
|
+
RUBY
|
63
|
+
end
|
64
|
+
|
56
65
|
def mutate!
|
57
66
|
@values = @obj.public_send("#{@attr.name}=", @values).values
|
58
67
|
end
|
data/lib/enumerize/value.rb
CHANGED
@@ -2,6 +2,8 @@ require 'i18n'
|
|
2
2
|
|
3
3
|
module Enumerize
|
4
4
|
class Value < String
|
5
|
+
include Predicatable
|
6
|
+
|
5
7
|
def initialize(attr, name, value=nil)
|
6
8
|
@attr = attr
|
7
9
|
@value = value || name.to_s
|
@@ -17,38 +19,21 @@ module Enumerize
|
|
17
19
|
I18n.t(i18n_keys[0], :default => i18n_keys[1..-1])
|
18
20
|
end
|
19
21
|
|
20
|
-
def method_missing(method, *args, &block)
|
21
|
-
if boolean_method?(method)
|
22
|
-
define_query_methods
|
23
|
-
send(method, *args, &block)
|
24
|
-
else
|
25
|
-
super
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def respond_to_missing?(method, include_private=false)
|
30
|
-
boolean_method?(method)
|
31
|
-
end
|
32
|
-
|
33
22
|
private
|
34
23
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def #{value}?
|
40
|
-
#{value == self}
|
41
|
-
end
|
42
|
-
RUBY
|
24
|
+
def define_query_method(value)
|
25
|
+
singleton_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
26
|
+
def #{value}?
|
27
|
+
#{value == self}
|
43
28
|
end
|
44
|
-
|
29
|
+
RUBY
|
45
30
|
end
|
46
31
|
|
47
32
|
def i18n_keys
|
48
33
|
@i18n_keys ||= begin
|
49
34
|
i18n_keys = []
|
50
|
-
i18n_keys << i18n_scope
|
51
35
|
i18n_keys << i18n_scope(i18n_suffix)
|
36
|
+
i18n_keys << i18n_scope
|
52
37
|
i18n_keys << self.humanize # humanize value if there are no translations
|
53
38
|
end
|
54
39
|
end
|
@@ -60,9 +45,5 @@ module Enumerize
|
|
60
45
|
def i18n_suffix
|
61
46
|
"#{@attr.i18n_suffix}." if @attr.i18n_suffix
|
62
47
|
end
|
63
|
-
|
64
|
-
def boolean_method?(method)
|
65
|
-
method[-1] == '?' && @attr.values.include?(method[0..-2])
|
66
|
-
end
|
67
48
|
end
|
68
49
|
end
|
data/lib/enumerize/version.rb
CHANGED
data/test/activerecord_test.rb
CHANGED
@@ -12,6 +12,7 @@ ActiveRecord::Base.connection.instance_eval do
|
|
12
12
|
create_table :users do |t|
|
13
13
|
t.string :sex
|
14
14
|
t.string :role
|
15
|
+
t.string :lambda_role
|
15
16
|
t.string :name
|
16
17
|
t.string :interests
|
17
18
|
t.string :status
|
@@ -36,6 +37,7 @@ end
|
|
36
37
|
module RoleEnum
|
37
38
|
extend Enumerize
|
38
39
|
enumerize :role, :in => [:user, :admin], :default => :user, scope: :having_role
|
40
|
+
enumerize :lambda_role, :in => [:user, :admin], :default => lambda { :admin }
|
39
41
|
end
|
40
42
|
|
41
43
|
class User < ActiveRecord::Base
|
@@ -82,6 +84,19 @@ describe Enumerize::ActiveRecord do
|
|
82
84
|
User.new.attributes['role'].must_equal 'user'
|
83
85
|
end
|
84
86
|
|
87
|
+
it 'has default value with lambda' do
|
88
|
+
User.new.lambda_role.must_equal 'admin'
|
89
|
+
User.new.attributes['lambda_role'].must_equal 'admin'
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'uses after_initialize callback to set default value' do
|
93
|
+
User.delete_all
|
94
|
+
User.create!(sex: 'male', lambda_role: nil)
|
95
|
+
|
96
|
+
user = User.where(:sex => 'male').first
|
97
|
+
user.lambda_role.must_equal 'admin'
|
98
|
+
end
|
99
|
+
|
85
100
|
it 'uses default value from db column' do
|
86
101
|
User.new.account_type.must_equal 'basic'
|
87
102
|
end
|
@@ -102,6 +117,13 @@ describe Enumerize::ActiveRecord do
|
|
102
117
|
user.errors[:role].must_include 'is not included in the list'
|
103
118
|
end
|
104
119
|
|
120
|
+
it 'validates inclusion when using write_attribute' do
|
121
|
+
user = User.new
|
122
|
+
user.send(:write_attribute, :role, 'wrong')
|
123
|
+
user.wont_be :valid?
|
124
|
+
user.errors[:role].must_include 'is not included in the list'
|
125
|
+
end
|
126
|
+
|
105
127
|
it 'validates inclusion on mass assignment' do
|
106
128
|
assert_raises ActiveRecord::RecordInvalid do
|
107
129
|
User.create!(role: 'wrong')
|
data/test/base_test.rb
CHANGED
@@ -78,6 +78,16 @@ describe Enumerize::Base do
|
|
78
78
|
object.foo.must_equal 'b'
|
79
79
|
end
|
80
80
|
|
81
|
+
it 'handles default value with lambda' do
|
82
|
+
klass.enumerize(:foo, :in => [:a, :b], :default => lambda { :b })
|
83
|
+
object.foo.must_equal 'b'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'injects object instance into lamda default value' do
|
87
|
+
klass.enumerize(:foo, :in => [:a, :b], :default => lambda { |obj| :b if obj.is_a? klass })
|
88
|
+
object.foo.must_equal 'b'
|
89
|
+
end
|
90
|
+
|
81
91
|
it 'raises exception on invalid default value' do
|
82
92
|
proc {
|
83
93
|
klass.enumerize(:foo, :in => [:a, :b], :default => :c)
|
@@ -168,7 +178,7 @@ describe Enumerize::Base do
|
|
168
178
|
object.attributes.must_equal(:foo => 'test')
|
169
179
|
end
|
170
180
|
|
171
|
-
it '
|
181
|
+
it 'stores hash values' do
|
172
182
|
klass.enumerize(:foo, :in => {:a => 1, :b => 2})
|
173
183
|
|
174
184
|
object.foo = :a
|
@@ -179,4 +189,14 @@ describe Enumerize::Base do
|
|
179
189
|
object.instance_variable_get(:@foo).must_equal 2
|
180
190
|
object.foo.must_equal 'b'
|
181
191
|
end
|
192
|
+
|
193
|
+
it 'returns custom value' do
|
194
|
+
klass.enumerize(:foo, :in => {:a => 1, :b => 2})
|
195
|
+
|
196
|
+
object.foo = :a
|
197
|
+
object.foo_value.must_equal 1
|
198
|
+
|
199
|
+
object.foo = :b
|
200
|
+
object.foo_value.must_equal 2
|
201
|
+
end
|
182
202
|
end
|
data/test/formtastic_test.rb
CHANGED
@@ -26,4 +26,25 @@ class ModuleAttributesSpec < MiniTest::Spec
|
|
26
26
|
klass.new.sex.must_equal 'male'
|
27
27
|
klass.sex.must_be_instance_of Enumerize::Attribute
|
28
28
|
end
|
29
|
+
|
30
|
+
it 'validates attributes' do
|
31
|
+
mod = Module.new do
|
32
|
+
extend Enumerize
|
33
|
+
enumerize :sex, :in => %w[male female]
|
34
|
+
end
|
35
|
+
|
36
|
+
klass = Class.new do
|
37
|
+
include ActiveModel::Validations
|
38
|
+
include mod
|
39
|
+
|
40
|
+
def self.model_name
|
41
|
+
ActiveModel::Name.new(self, nil, 'name')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
object = klass.new
|
46
|
+
object.sex = 'wrong'
|
47
|
+
object.wont_be :valid?
|
48
|
+
object.errors[:sex].must_include 'is not included in the list'
|
49
|
+
end
|
29
50
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
silence_warnings do
|
4
|
+
require 'mongo_mapper'
|
5
|
+
end
|
6
|
+
|
7
|
+
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
|
8
|
+
MongoMapper.database = 'enumerize-test-suite-of-mongomapper'
|
9
|
+
|
10
|
+
describe Enumerize do
|
11
|
+
class MongoMapperUser
|
12
|
+
include MongoMapper::Document
|
13
|
+
extend Enumerize
|
14
|
+
|
15
|
+
key :sex
|
16
|
+
key :role
|
17
|
+
|
18
|
+
enumerize :sex, :in => %w[male female]
|
19
|
+
enumerize :role, :in => %w[admin user], :default => 'user'
|
20
|
+
end
|
21
|
+
|
22
|
+
before { $VERBOSE = nil }
|
23
|
+
after { $VERBOSE = true }
|
24
|
+
|
25
|
+
let(:model) { MongoMapperUser }
|
26
|
+
|
27
|
+
it 'sets nil if invalid value is passed' do
|
28
|
+
user = model.new
|
29
|
+
user.sex = :invalid
|
30
|
+
user.sex.must_equal nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'saves value' do
|
34
|
+
model.delete_all
|
35
|
+
user = model.new
|
36
|
+
user.sex = :female
|
37
|
+
user.save!
|
38
|
+
user.sex.must_equal 'female'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'loads value' do
|
42
|
+
model.delete_all
|
43
|
+
model.create!(:sex => :male)
|
44
|
+
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
|
45
|
+
user = model.first
|
46
|
+
user.sex.must_equal 'male'
|
47
|
+
user.sex_text.must_equal 'Male'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'has default value' do
|
52
|
+
model.new.role.must_equal 'user'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'validates inclusion' do
|
56
|
+
user = model.new
|
57
|
+
user.role = 'wrong'
|
58
|
+
user.wont_be :valid?
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'assigns value on loaded record' do
|
62
|
+
model.delete_all
|
63
|
+
model.create!(:sex => :male)
|
64
|
+
user = model.first
|
65
|
+
user.sex = :female
|
66
|
+
user.sex.must_equal 'female'
|
67
|
+
end
|
68
|
+
end
|
data/test/mongoid_test.rb
CHANGED
data/test/multiple_test.rb
CHANGED
@@ -28,4 +28,9 @@ describe Enumerize::Base do
|
|
28
28
|
klass.enumerize :foos, in: %w(a b c), multiple: true
|
29
29
|
object.wont_respond_to :foos_text
|
30
30
|
end
|
31
|
+
|
32
|
+
it "doesn't define _value method" do
|
33
|
+
klass.enumerize :foos, in: %w(a b c), multiple: true
|
34
|
+
object.wont_respond_to :foos_value
|
35
|
+
end
|
31
36
|
end
|
data/test/predicates_test.rb
CHANGED
@@ -15,6 +15,12 @@ describe Enumerize::Predicates do
|
|
15
15
|
object.must_respond_to :b?
|
16
16
|
end
|
17
17
|
|
18
|
+
it 'creates predicate methods on multiple attribute' do
|
19
|
+
klass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
|
20
|
+
object.must_respond_to :a?
|
21
|
+
object.must_respond_to :b?
|
22
|
+
end
|
23
|
+
|
18
24
|
it 'checks values' do
|
19
25
|
klass.enumerize(:foo, in: %w(a b), predicates: true)
|
20
26
|
object.foo = 'a'
|
@@ -22,6 +28,13 @@ describe Enumerize::Predicates do
|
|
22
28
|
object.b?.must_equal false
|
23
29
|
end
|
24
30
|
|
31
|
+
it 'checks values on multiple attribute' do
|
32
|
+
klass.enumerize(:foo, in: %w(a b), predicates: true, multiple: true)
|
33
|
+
object.foo << :a
|
34
|
+
object.a?.must_equal true
|
35
|
+
object.b?.must_equal false
|
36
|
+
end
|
37
|
+
|
25
38
|
it 'prefixes methods' do
|
26
39
|
klass.enumerize(:foo, in: %w(a b), predicates: { prefix: 'bar' })
|
27
40
|
object.wont_respond_to :a?
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'enumerize/integrations/rspec'
|
3
|
+
|
4
|
+
describe Enumerize::Integrations::RSpec do
|
5
|
+
class Should
|
6
|
+
include Enumerize::Integrations::RSpec
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:klass) do
|
10
|
+
Class.new do
|
11
|
+
extend Enumerize
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:should) { Should.new }
|
16
|
+
let(:object) { klass.new }
|
17
|
+
|
18
|
+
describe '#matches?' do
|
19
|
+
before do
|
20
|
+
klass.enumerize(:sex, :in => [:male, :female])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns true' do
|
24
|
+
matcher = should.enumerize(:sex).in(:male, :female)
|
25
|
+
matcher.matches?(object).must_equal true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns false' do
|
29
|
+
matcher = should.enumerize(:sex).in(:bar)
|
30
|
+
matcher.matches?(object).must_equal false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#failure_message' do
|
35
|
+
before do
|
36
|
+
klass.enumerize(:sex, :in => [:male, :female], :default => :male)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns failure message for invalid :in option' do
|
40
|
+
matcher = should.enumerize(:sex).in(:bar)
|
41
|
+
matcher.subject = object
|
42
|
+
expected = ' expected :sex to allow value: "bar", but it allows "female", "male" instead'
|
43
|
+
matcher.failure_message.must_equal expected
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns failure message for invalid :with_default option' do
|
47
|
+
matcher = should.enumerize(:sex).in(:male, :female).with_default(:foo)
|
48
|
+
matcher.subject = object
|
49
|
+
expected = ' expected :sex to have "foo" as default value, but it sets "male" instead'
|
50
|
+
matcher.failure_message.must_equal expected
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/test/rspec_spec.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'enumerize'
|
2
|
+
require 'rspec'
|
3
|
+
|
4
|
+
class RSpecUser
|
5
|
+
extend Enumerize
|
6
|
+
|
7
|
+
enumerize :sex, in: [:male, :female], default: :male
|
8
|
+
end
|
9
|
+
|
10
|
+
describe RSpecUser do
|
11
|
+
it { should enumerize(:sex).in(:male, :female) }
|
12
|
+
it { should enumerize(:sex).in(:male, :female).with_default(:male) }
|
13
|
+
end
|
data/test/set_test.rb
CHANGED
@@ -109,4 +109,42 @@ describe Enumerize::Set do
|
|
109
109
|
set.join(', ').must_equal 'a, b'
|
110
110
|
end
|
111
111
|
end
|
112
|
+
|
113
|
+
describe 'boolean methods comparison' do
|
114
|
+
it 'returns true if value equals method' do
|
115
|
+
set << :a
|
116
|
+
set.a?.must_equal true
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'returns false if value does not equal method' do
|
120
|
+
set << :a
|
121
|
+
set.b?.must_equal false
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'raises NoMethodError if there are no values like boolean method' do
|
125
|
+
proc {
|
126
|
+
set.some_method?
|
127
|
+
}.must_raise NoMethodError
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'raises ArgumentError if arguments are passed' do
|
131
|
+
proc {
|
132
|
+
set.a?('<3')
|
133
|
+
}.must_raise ArgumentError
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'responds to methods for existing values' do
|
137
|
+
set.must_respond_to :a?
|
138
|
+
set.must_respond_to :b?
|
139
|
+
set.must_respond_to :c?
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'returns a method object' do
|
143
|
+
set.method(:a?).must_be_instance_of Method
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'does not respond to a method for not existing value' do
|
147
|
+
set.wont_respond_to :some_method?
|
148
|
+
end
|
149
|
+
end
|
112
150
|
end
|
data/test/simple_form_test.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -5,20 +5,6 @@ require 'active_model'
|
|
5
5
|
|
6
6
|
$VERBOSE=true
|
7
7
|
|
8
|
-
module SimpleForm
|
9
|
-
module Rails
|
10
|
-
def self.env
|
11
|
-
ActiveSupport::StringInquirer.new("test")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module Formtastic
|
17
|
-
module Rails
|
18
|
-
VERSION = ActiveSupport::VERSION
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
8
|
module RailsAdmin
|
23
9
|
end
|
24
10
|
|
data/test/value_test.rb
CHANGED
@@ -12,6 +12,34 @@ describe Enumerize::Value do
|
|
12
12
|
value.must_be :==, 'test_value'
|
13
13
|
end
|
14
14
|
|
15
|
+
describe 'translation' do
|
16
|
+
let(:attr) { Struct.new(:values, :name, :i18n_suffix).new([], "attribute_name", "model_name") }
|
17
|
+
|
18
|
+
it 'uses common translation' do
|
19
|
+
store_translations(:en, :enumerize => {:attribute_name => {:test_value => "Common translation"}}) do
|
20
|
+
value.text.must_be :==, "Common translation"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'uses model specific translation' do
|
25
|
+
store_translations(:en, :enumerize => {:model_name => {:attribute_name => {:test_value => "Model Specific translation"}}}) do
|
26
|
+
value.text.must_be :==, "Model Specific translation"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'uses model specific translation rather than common translation' do
|
31
|
+
store_translations(:en, :enumerize => {:attribute_name => {:test_value => "Common translation"}, :model_name => {:attribute_name => {:test_value => "Model Specific translation"}}}) do
|
32
|
+
value.text.must_be :==, "Model Specific translation"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'uses simply humanized value when translation is undefined' do
|
37
|
+
store_translations(:en, :enumerize => {}) do
|
38
|
+
value.text.must_be :==, "Test value"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
15
43
|
describe 'boolean methods comparison' do
|
16
44
|
before do
|
17
45
|
attr.values = [value, Enumerize::Value.new(attr, 'other_value')]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumerize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -27,7 +27,8 @@ dependencies:
|
|
27
27
|
none: false
|
28
28
|
prerelease: false
|
29
29
|
name: activesupport
|
30
|
-
description: Enumerated attributes with I18n and ActiveRecord/Mongoid
|
30
|
+
description: Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper
|
31
|
+
support
|
31
32
|
email: team@brainspec.com
|
32
33
|
executables: []
|
33
34
|
extensions: []
|
@@ -51,8 +52,11 @@ files:
|
|
51
52
|
- lib/enumerize/hooks/formtastic.rb
|
52
53
|
- lib/enumerize/hooks/simple_form.rb
|
53
54
|
- lib/enumerize/integrations/rails_admin.rb
|
55
|
+
- lib/enumerize/integrations/rspec.rb
|
56
|
+
- lib/enumerize/integrations/rspec/matcher.rb
|
54
57
|
- lib/enumerize/module.rb
|
55
58
|
- lib/enumerize/module_attributes.rb
|
59
|
+
- lib/enumerize/predicatable.rb
|
56
60
|
- lib/enumerize/predicates.rb
|
57
61
|
- lib/enumerize/set.rb
|
58
62
|
- lib/enumerize/value.rb
|
@@ -63,10 +67,13 @@ files:
|
|
63
67
|
- test/base_test.rb
|
64
68
|
- test/formtastic_test.rb
|
65
69
|
- test/module_attributes_test.rb
|
70
|
+
- test/mongo_mapper_test.rb
|
66
71
|
- test/mongoid_test.rb
|
67
72
|
- test/multiple_test.rb
|
68
73
|
- test/predicates_test.rb
|
69
74
|
- test/rails_admin_test.rb
|
75
|
+
- test/rspec_matcher_test.rb
|
76
|
+
- test/rspec_spec.rb
|
70
77
|
- test/set_test.rb
|
71
78
|
- test/simple_form_test.rb
|
72
79
|
- test/support/mock_controller.rb
|
@@ -89,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
96
|
requirements:
|
90
97
|
- - ! '>='
|
91
98
|
- !ruby/object:Gem::Version
|
92
|
-
hash:
|
99
|
+
hash: 2859816307703102675
|
93
100
|
version: '0'
|
94
101
|
segments:
|
95
102
|
- 0
|
@@ -99,5 +106,5 @@ rubyforge_project:
|
|
99
106
|
rubygems_version: 1.8.23
|
100
107
|
signing_key:
|
101
108
|
specification_version: 3
|
102
|
-
summary: Enumerated attributes with I18n and ActiveRecord/Mongoid support
|
109
|
+
summary: Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support
|
103
110
|
test_files: []
|