enumerize 0.0.4 → 0.1.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/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +10 -3
- data/Gemfile +3 -1
- data/README.md +33 -1
- data/enumerize.gemspec +2 -2
- data/gemfiles/Gemfile-ar-3.1.x +14 -0
- data/lib/enumerize.rb +17 -4
- data/lib/enumerize/activerecord.rb +7 -0
- data/lib/enumerize/attribute.rb +2 -2
- data/lib/enumerize/base.rb +72 -0
- data/lib/enumerize/hooks/formtastic.rb +28 -0
- data/lib/enumerize/hooks/simple_form.rb +24 -0
- data/lib/enumerize/value.rb +47 -9
- data/lib/enumerize/version.rb +1 -1
- data/test/activerecord_test.rb +7 -5
- data/test/attribute_test.rb +9 -3
- data/test/base_test.rb +93 -0
- data/test/formtastic_test.rb +67 -0
- data/test/mongoid_test.rb +5 -4
- data/test/simple_form_test.rb +50 -0
- data/test/support/mock_controller.rb +21 -0
- data/test/support/view_test_helper.rb +29 -0
- data/test/test_helper.rb +27 -0
- data/test/value_test.rb +9 -4
- metadata +24 -14
- data/lib/enumerize/integrations.rb +0 -6
- data/lib/enumerize/integrations/active_record.rb +0 -9
- data/lib/enumerize/integrations/basic.rb +0 -63
- data/test/basic_test.rb +0 -69
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
language: ruby
|
2
|
+
before_install:
|
3
|
+
- gem install bundler --pre
|
2
4
|
rvm:
|
3
5
|
- 1.9.2
|
4
6
|
- 1.9.3
|
7
|
+
gemfile:
|
8
|
+
- gemfiles/Gemfile-ar-3.1.x
|
9
|
+
- Gemfile
|
5
10
|
notifications:
|
6
11
|
email:
|
7
12
|
recipients:
|
8
13
|
- sergey.nartimov@twinslash.com
|
14
|
+
- vasily.ermolovich@twinslash.com
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,17 @@
|
|
1
|
+
## 0.1.0 (March 5, 2012) ##
|
2
|
+
|
3
|
+
### enhancements
|
4
|
+
* Return humanized value if there are no translations (by [@nashby](https://github.com/nashby))
|
5
|
+
* Integration with SimpleForm (by [@nashby](https://github.com/nashby))
|
6
|
+
* Integration with Formtastic (by [@lest](https://github.com/lest))
|
7
|
+
|
1
8
|
## 0.0.4 (February 8, 2012) ##
|
2
9
|
|
3
10
|
### bug fix
|
4
|
-
* Make attribute accessors to work with ActiveRecord 3.1.x (by @lest)
|
11
|
+
* Make attribute accessors to work with ActiveRecord 3.1.x (by [@lest](https://github.com/lest))
|
5
12
|
|
6
13
|
## 0.0.3 (February 8, 2012) ##
|
7
14
|
|
8
15
|
### enhancements
|
9
|
-
* Mongoid support (by @lest)
|
10
|
-
* Boolean methods (by @Dreamfa11)
|
16
|
+
* Mongoid support (by [@lest](https://github.com/lest))
|
17
|
+
* Boolean methods (by [@Dreamfa11](https://github.com/Dreamfa11))
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Enumerize [](http://travis-ci.org/twinslash/enumerize) [](https://gemnasium.com/twinslash/enumerize)
|
2
2
|
|
3
|
-
Enumerated attributes with I18n and ActiveRecord support
|
3
|
+
Enumerated attributes with I18n and ActiveRecord/Mongoid support
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -87,6 +87,38 @@ use it with forms:
|
|
87
87
|
<% end %>
|
88
88
|
```
|
89
89
|
|
90
|
+
If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
|
91
|
+
|
92
|
+
```erb
|
93
|
+
<%= simple_form_for @user do |f| %>
|
94
|
+
<%= f.input :sex %>
|
95
|
+
<% end %>
|
96
|
+
```
|
97
|
+
|
98
|
+
and if you want it as radio buttons:
|
99
|
+
|
100
|
+
```erb
|
101
|
+
<%= simple_form_for @user do |f| %>
|
102
|
+
<%= f.input :sex, :as => :radio_buttons %>
|
103
|
+
<% end %>
|
104
|
+
```
|
105
|
+
|
106
|
+
If you are using Formtastic gem you also don't need to specify input type (`:select` by default) and collection:
|
107
|
+
|
108
|
+
```erb
|
109
|
+
<%= semantic_form_for @user do |f| %>
|
110
|
+
<%= f.input :sex %>
|
111
|
+
<% end %>
|
112
|
+
```
|
113
|
+
|
114
|
+
and if you want it as radio buttons:
|
115
|
+
|
116
|
+
```erb
|
117
|
+
<%= semantic_form_for @user do |f| %>
|
118
|
+
<%= f.input :sex, :as => :radio %>
|
119
|
+
<% end %>
|
120
|
+
```
|
121
|
+
|
90
122
|
Boolean methods:
|
91
123
|
|
92
124
|
```ruby
|
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 = "info@twinslash.com"
|
7
|
-
gem.description = %q{Enumerated attributes with I18n and ActiveRecord support}
|
8
|
-
gem.summary = %q{Enumerated attributes with I18n and ActiveRecord support}
|
7
|
+
gem.description = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid support}
|
8
|
+
gem.summary = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid support}
|
9
9
|
gem.homepage = "https://github.com/twinslash/enumerize"
|
10
10
|
|
11
11
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'enumerize', :path => '..'
|
4
|
+
|
5
|
+
gem 'rake'
|
6
|
+
gem 'minitest', '~> 2.11.0'
|
7
|
+
gem 'mocha'
|
8
|
+
|
9
|
+
gem 'activerecord', '~> 3.1.0'
|
10
|
+
gem 'sqlite3'
|
11
|
+
|
12
|
+
gem 'mongoid'
|
13
|
+
gem 'simple_form', '~> 1.5.2'
|
14
|
+
gem 'formtastic', '~> 1.2.4'
|
data/lib/enumerize.rb
CHANGED
@@ -4,15 +4,28 @@ require 'enumerize/version'
|
|
4
4
|
module Enumerize
|
5
5
|
autoload :Attribute, 'enumerize/attribute'
|
6
6
|
autoload :Value, 'enumerize/value'
|
7
|
-
autoload :
|
7
|
+
autoload :Base, 'enumerize/base'
|
8
|
+
autoload :ActiveRecord, 'enumerize/activerecord'
|
8
9
|
|
9
10
|
extend ActiveSupport::Concern
|
10
11
|
|
11
|
-
include
|
12
|
+
include Enumerize::Base
|
12
13
|
|
13
14
|
included do
|
14
|
-
if defined?(ActiveRecord::Base) && self < ActiveRecord::Base
|
15
|
-
include
|
15
|
+
if defined?(::ActiveRecord::Base) && self < ::ActiveRecord::Base
|
16
|
+
include Enumerize::ActiveRecord
|
16
17
|
end
|
17
18
|
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
require 'simple_form'
|
22
|
+
require 'enumerize/hooks/simple_form'
|
23
|
+
rescue LoadError
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require 'formtastic'
|
28
|
+
require 'enumerize/hooks/formtastic'
|
29
|
+
rescue LoadError
|
30
|
+
end
|
18
31
|
end
|
data/lib/enumerize/attribute.rb
CHANGED
@@ -6,12 +6,12 @@ module Enumerize
|
|
6
6
|
raise ArgumentError, ':in option is required' unless options[:in]
|
7
7
|
|
8
8
|
@klass = klass
|
9
|
-
@name = name
|
9
|
+
@name = name.to_sym
|
10
10
|
@values = Array(options[:in]).map { |v| Value.new(self, v) }
|
11
11
|
@value_hash = Hash[@values.map { |v| [v.to_s, v] }]
|
12
12
|
|
13
13
|
if options[:default]
|
14
|
-
@default_value =
|
14
|
+
@default_value = find_value(options[:default])
|
15
15
|
raise ArgumentError, 'invalid default value' unless @default_value
|
16
16
|
end
|
17
17
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module Base
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
@enumerized_attributes = {}
|
9
|
+
class << self
|
10
|
+
attr_reader :enumerized_attributes
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def enumerize(*args, &block)
|
16
|
+
attr = Attribute.new(self, *args, &block)
|
17
|
+
enumerized_attributes[attr.name] = attr
|
18
|
+
|
19
|
+
unless methods.include?(attr.name)
|
20
|
+
singleton_class.class_eval do
|
21
|
+
define_method(attr.name) { attr }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
mod = Module.new
|
26
|
+
|
27
|
+
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
28
|
+
def initialize(*, &_)
|
29
|
+
super
|
30
|
+
self.#{attr.name} = self.class.enumerized_attributes[:#{attr.name}].default_value if #{attr.name}.nil?
|
31
|
+
end
|
32
|
+
RUBY
|
33
|
+
|
34
|
+
_define_enumerize_attribute(mod, attr)
|
35
|
+
|
36
|
+
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
37
|
+
def #{attr.name}_text
|
38
|
+
#{attr.name} && #{attr.name}.text
|
39
|
+
end
|
40
|
+
RUBY
|
41
|
+
|
42
|
+
include mod
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def _define_enumerize_attribute(mod, attr)
|
48
|
+
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
49
|
+
def #{attr.name}
|
50
|
+
if respond_to?(:read_attribute, true)
|
51
|
+
self.class.enumerized_attributes[:#{attr.name}].find_value(read_attribute(:#{attr.name}))
|
52
|
+
else
|
53
|
+
if defined?(@#{attr.name})
|
54
|
+
self.class.enumerized_attributes[:#{attr.name}].find_value(@#{attr.name})
|
55
|
+
else
|
56
|
+
@#{attr.name} = nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def #{attr.name}=(new_value)
|
62
|
+
if respond_to?(:write_attribute, true)
|
63
|
+
write_attribute :#{attr.name}, self.class.enumerized_attributes[:#{attr.name}].find_value(new_value).to_s
|
64
|
+
else
|
65
|
+
@#{attr.name} = self.class.enumerized_attributes[:#{attr.name}].find_value(new_value).to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
RUBY
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module Hooks
|
5
|
+
module FormtasticFormBuilderExtension
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
alias_method_chain :input, :enumerize
|
10
|
+
end
|
11
|
+
|
12
|
+
def input_with_enumerize(method, options={})
|
13
|
+
klass = object.class
|
14
|
+
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
|
15
|
+
options[:collection] ||= attr.options
|
16
|
+
end
|
17
|
+
|
18
|
+
input_without_enumerize(method, options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if defined? ::Formtastic::SemanticFormBuilder
|
25
|
+
::Formtastic::SemanticFormBuilder.send :include, Enumerize::Hooks::FormtasticFormBuilderExtension
|
26
|
+
else
|
27
|
+
::Formtastic::FormBuilder.send :include, Enumerize::Hooks::FormtasticFormBuilderExtension
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module Hooks
|
5
|
+
module SimpleFormBuilderExtension
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
alias_method_chain :input, :enumerize
|
10
|
+
end
|
11
|
+
|
12
|
+
def input_with_enumerize(attribute_name, options={}, &block)
|
13
|
+
klass = object.class
|
14
|
+
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[attribute_name])
|
15
|
+
options[:collection] ||= attr.options
|
16
|
+
end
|
17
|
+
|
18
|
+
input_without_enumerize(attribute_name, options, &block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
::SimpleForm::FormBuilder.send :include, Enumerize::Hooks::SimpleFormBuilderExtension
|
data/lib/enumerize/value.rb
CHANGED
@@ -6,21 +6,59 @@ module Enumerize
|
|
6
6
|
@attr = attr
|
7
7
|
|
8
8
|
super(value.to_s)
|
9
|
-
freeze
|
10
9
|
end
|
11
10
|
|
12
11
|
def text
|
13
|
-
i18n_keys = ['']
|
14
|
-
i18n_keys.unshift "#{@attr.i18n_suffix}." if @attr.i18n_suffix
|
15
|
-
i18n_keys.map! { |k| :"enumerize.#{k}#{@attr.name}.#{self}" }
|
16
12
|
I18n.t(i18n_keys.shift, :default => i18n_keys)
|
17
13
|
end
|
18
14
|
|
19
|
-
def method_missing(method, *args)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
if method[-1] == '?' && @attr.values.include?(method[0..-2])
|
17
|
+
define_query_methods
|
18
|
+
send(method, *args, &block)
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(method, include_private=false)
|
25
|
+
if super
|
26
|
+
true
|
27
|
+
elsif method[-1] == '?' && @attr.values.include?(method[0..-2])
|
28
|
+
define_query_methods
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def define_query_methods
|
36
|
+
@attr.values.each do |value|
|
37
|
+
unless singleton_methods.include?(:"#{value}?")
|
38
|
+
singleton_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
39
|
+
def #{value}?
|
40
|
+
#{value == self}
|
41
|
+
end
|
42
|
+
RUBY
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def i18n_keys
|
48
|
+
@i18n_keys ||= begin
|
49
|
+
i18n_keys = []
|
50
|
+
i18n_keys << i18n_scope
|
51
|
+
i18n_keys << i18n_scope(i18n_suffix)
|
52
|
+
i18n_keys << self.humanize # humanize value if there are no translations
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def i18n_scope(suffix = nil)
|
57
|
+
:"enumerize.#{suffix}#{@attr.name}.#{self}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def i18n_suffix
|
61
|
+
"#{@attr.i18n_suffix}." if @attr.i18n_suffix
|
24
62
|
end
|
25
63
|
end
|
26
64
|
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 :name
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
@@ -23,7 +24,7 @@ class User < ActiveRecord::Base
|
|
23
24
|
enumerize :role, :in => [:user, :admin], :default => :user
|
24
25
|
end
|
25
26
|
|
26
|
-
describe Enumerize::
|
27
|
+
describe Enumerize::ActiveRecord do
|
27
28
|
it 'sets nil if invalid value is passed' do
|
28
29
|
user = User.new
|
29
30
|
user.sex = :invalid
|
@@ -40,11 +41,12 @@ describe Enumerize::Integrations::ActiveRecord do
|
|
40
41
|
|
41
42
|
it 'loads value' do
|
42
43
|
User.delete_all
|
43
|
-
I18n.backend.store_translations(:en, :enumerize => {:sex => {:male => 'Male'}})
|
44
44
|
User.create!(:sex => :male)
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
|
46
|
+
user = User.first
|
47
|
+
user.sex.must_equal 'male'
|
48
|
+
user.sex_text.must_equal 'Male'
|
49
|
+
end
|
48
50
|
end
|
49
51
|
|
50
52
|
it 'has default value' do
|
data/test/attribute_test.rb
CHANGED
@@ -14,9 +14,15 @@ describe Enumerize::Attribute do
|
|
14
14
|
attr.values.must_equal %w[a b]
|
15
15
|
end
|
16
16
|
|
17
|
+
it 'converts name to symbol' do
|
18
|
+
build_attr nil, 'foo', :in => %w[a b]
|
19
|
+
attr.name.must_equal :foo
|
20
|
+
end
|
21
|
+
|
17
22
|
it 'returns options for select' do
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
store_translations(:en, :enumerize => {:foo => {:a => 'a text', :b => 'b text'}}) do
|
24
|
+
build_attr nil, :foo, :in => %w[a b]
|
25
|
+
attr.options.must_equal [['a text', 'a'], ['b text', 'b']]
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
data/test/base_test.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Enumerize::Base do
|
4
|
+
let(:klass) do
|
5
|
+
Class.new do
|
6
|
+
include Enumerize
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:object) { klass.new }
|
11
|
+
|
12
|
+
it 'returns nil when not set' do
|
13
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
14
|
+
object.foo.must_equal nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns value that was set' do
|
18
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
19
|
+
object.foo = :a
|
20
|
+
object.foo.must_equal 'a'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns translation' do
|
24
|
+
store_translations(:en, :enumerize => {:foo => {:a => 'a text'}}) do
|
25
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
26
|
+
object.foo = :a
|
27
|
+
object.foo.text.must_equal 'a text'
|
28
|
+
object.foo_text.must_equal 'a text'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns nil as translation when value is nil' do
|
33
|
+
store_translations(:en, :enumerize => {:foo => {:a => 'a text'}}) do
|
34
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
35
|
+
object.foo_text.must_equal nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'scopes translation by i18 key' do
|
40
|
+
def klass.model_name
|
41
|
+
name = "ExampleClass"
|
42
|
+
def name.i18n_key
|
43
|
+
'example_class'
|
44
|
+
end
|
45
|
+
|
46
|
+
name
|
47
|
+
end
|
48
|
+
|
49
|
+
store_translations(:en, :enumerize => {:example_class => {:foo => {:a => 'a text scoped'}}}) do
|
50
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
51
|
+
object.foo = :a
|
52
|
+
object.foo.text.must_equal 'a text scoped'
|
53
|
+
object.foo_text.must_equal 'a text scoped'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns humanized value if there are no translations' do
|
58
|
+
store_translations(:en, :enumerize => {}) do
|
59
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
60
|
+
object.foo = :a
|
61
|
+
object.foo_text.must_equal 'A'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'stores value as string' do
|
66
|
+
klass.enumerize(:foo, :in => [:a, :b])
|
67
|
+
object.foo = :a
|
68
|
+
object.instance_variable_get(:@foo).must_be_instance_of String
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'handles default value' do
|
72
|
+
klass.enumerize(:foo, :in => [:a, :b], :default => :b)
|
73
|
+
object.foo.must_equal 'b'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'raises exception on invalid default value' do
|
77
|
+
proc {
|
78
|
+
klass.enumerize(:foo, :in => [:a, :b], :default => :c)
|
79
|
+
}.must_raise ArgumentError
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'has enumerized attributes' do
|
83
|
+
klass.enumerized_attributes.must_equal({})
|
84
|
+
klass.enumerize(:foo, :in => %w[a b])
|
85
|
+
klass.enumerized_attributes[:foo].must_be_instance_of Enumerize::Attribute
|
86
|
+
end
|
87
|
+
|
88
|
+
it "doesn't override existing method" do
|
89
|
+
method = klass.method(:name)
|
90
|
+
klass.enumerize(:name, :in => %w[a b], :default => 'a')
|
91
|
+
klass.method(:name).must_equal method
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
if defined? Formtastic::Helpers::InputHelper
|
4
|
+
module Formtastic
|
5
|
+
module Helpers
|
6
|
+
module InputHelper
|
7
|
+
remove_method :input_class
|
8
|
+
def input_class(as)
|
9
|
+
input_class_with_const_defined(as)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class FormtasticSpec < MiniTest::Spec
|
17
|
+
include ViewTestHelper
|
18
|
+
if defined? Formtastic::SemanticFormHelper
|
19
|
+
include Formtastic::SemanticFormHelper
|
20
|
+
else
|
21
|
+
include Formtastic::Helpers::FormHelper
|
22
|
+
end
|
23
|
+
|
24
|
+
class User < Struct.new(:sex, :age)
|
25
|
+
extend ActiveModel::Naming
|
26
|
+
include ActiveModel::Conversion
|
27
|
+
|
28
|
+
include Enumerize
|
29
|
+
|
30
|
+
enumerize :sex, :in => [:male, :female]
|
31
|
+
|
32
|
+
def persisted?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
before { $VERBOSE = nil }
|
38
|
+
after { $VERBOSE = true }
|
39
|
+
|
40
|
+
let(:user) { User.new }
|
41
|
+
|
42
|
+
it 'renders select with enumerized values' do
|
43
|
+
concat(semantic_form_for(user) do |f|
|
44
|
+
f.input :sex
|
45
|
+
end)
|
46
|
+
|
47
|
+
assert_select 'select option[value=male]'
|
48
|
+
assert_select 'select option[value=female]'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'renders radio buttons with enumerized values' do
|
52
|
+
concat(semantic_form_for(user) do |f|
|
53
|
+
f.input :sex, :as => :radio
|
54
|
+
end)
|
55
|
+
|
56
|
+
assert_select 'input[type=radio][value=male]'
|
57
|
+
assert_select 'input[type=radio][value=female]'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not affect not enumerized attributes' do
|
61
|
+
concat(semantic_form_for(user) do |f|
|
62
|
+
f.input(:age)
|
63
|
+
end)
|
64
|
+
|
65
|
+
assert_select 'input[type=text]'
|
66
|
+
end
|
67
|
+
end
|
data/test/mongoid_test.rb
CHANGED
@@ -42,11 +42,12 @@ describe Enumerize do
|
|
42
42
|
|
43
43
|
it 'loads value' do
|
44
44
|
model.delete_all
|
45
|
-
I18n.backend.store_translations(:en, :enumerize => {:sex => {:male => 'Male'}})
|
46
45
|
model.create!(:sex => :male)
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
store_translations(:en, :enumerize => {:sex => {:male => 'Male'}}) do
|
47
|
+
user = model.first
|
48
|
+
user.sex.must_equal 'male'
|
49
|
+
user.sex_text.must_equal 'Male'
|
50
|
+
end
|
50
51
|
end
|
51
52
|
|
52
53
|
it 'has default value' do
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'simple_form/version'
|
3
|
+
|
4
|
+
class SimpleFormSpec < MiniTest::Spec
|
5
|
+
include ViewTestHelper
|
6
|
+
include SimpleForm::ActionViewExtensions::FormHelper
|
7
|
+
|
8
|
+
class User < Struct.new(:sex, :age)
|
9
|
+
extend ActiveModel::Naming
|
10
|
+
include ActiveModel::Conversion
|
11
|
+
|
12
|
+
include Enumerize
|
13
|
+
|
14
|
+
enumerize :sex, :in => [:male, :female]
|
15
|
+
|
16
|
+
def persisted?
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:user) { User.new }
|
22
|
+
|
23
|
+
it 'renders select with enumerized values' do
|
24
|
+
concat(simple_form_for(user) do |f|
|
25
|
+
f.input(:sex)
|
26
|
+
end)
|
27
|
+
|
28
|
+
assert_select 'select option[value=male]'
|
29
|
+
assert_select 'select option[value=female]'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'renders radio buttons with enumerated values' do
|
33
|
+
as = SimpleForm::VERSION > '2.0' ? :radio_buttons : :radio
|
34
|
+
|
35
|
+
concat(simple_form_for(user) do |f|
|
36
|
+
f.input(:sex, :as => as)
|
37
|
+
end)
|
38
|
+
|
39
|
+
assert_select 'input[type=radio][value=male]'
|
40
|
+
assert_select 'input[type=radio][value=female]'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not affect not enumerized attributes' do
|
44
|
+
concat(simple_form_for(user) do |f|
|
45
|
+
f.input(:age)
|
46
|
+
end)
|
47
|
+
|
48
|
+
assert_select 'input.string'
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class MockController
|
2
|
+
attr_writer :action_name
|
3
|
+
|
4
|
+
def _routes
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def action_name
|
9
|
+
defined?(@action_name) ? @action_name : "edit"
|
10
|
+
end
|
11
|
+
|
12
|
+
def url_for(*args)
|
13
|
+
"http://example.com"
|
14
|
+
end
|
15
|
+
|
16
|
+
def url_helpers
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def hash_for_users_path(*args); end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/testing/setup_and_teardown'
|
3
|
+
|
4
|
+
module ViewTestHelper
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
include ActiveSupport::Testing::SetupAndTeardown
|
8
|
+
include ActionView::TestCase::Behavior
|
9
|
+
|
10
|
+
included do
|
11
|
+
setup :set_controller
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_controller
|
15
|
+
@controller = MockController.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(method, *args)
|
19
|
+
super unless method.to_s =~ /_path$/
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to?(method, include_private=false)
|
23
|
+
method.to_s =~ /_path$/ || super
|
24
|
+
end
|
25
|
+
|
26
|
+
def protect_against_forgery?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -5,4 +5,31 @@ require 'active_support/core_ext/kernel/reporting'
|
|
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
|
+
|
8
16
|
require 'enumerize'
|
17
|
+
|
18
|
+
Dir["#{File.dirname(__FILE__)}/support/*.rb"].each do |file|
|
19
|
+
require file
|
20
|
+
end
|
21
|
+
|
22
|
+
module MiscHelpers
|
23
|
+
def store_translations(locale, translations, &block)
|
24
|
+
begin
|
25
|
+
I18n.backend.store_translations locale, translations
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
I18n.reload!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class MiniTest::Spec
|
34
|
+
include MiscHelpers
|
35
|
+
end
|
data/test/value_test.rb
CHANGED
@@ -12,10 +12,6 @@ describe Enumerize::Value do
|
|
12
12
|
value.must_be :==, 'test_value'
|
13
13
|
end
|
14
14
|
|
15
|
-
it 'is frozen' do
|
16
|
-
value.must_be :frozen?
|
17
|
-
end
|
18
|
-
|
19
15
|
describe 'boolean methods comparison' do
|
20
16
|
before do
|
21
17
|
attr.stubs(:values).returns([value, Enumerize::Value.new(attr, 'other_value')])
|
@@ -40,5 +36,14 @@ describe Enumerize::Value do
|
|
40
36
|
value.other_value?('<3')
|
41
37
|
}.must_raise ArgumentError
|
42
38
|
end
|
39
|
+
|
40
|
+
it 'responds to methods for existing values' do
|
41
|
+
value.must_respond_to :test_value?
|
42
|
+
value.must_respond_to :other_value?
|
43
|
+
end
|
44
|
+
|
45
|
+
it "doesn't respond to a method for not existing value" do
|
46
|
+
value.wont_respond_to :some_method?
|
47
|
+
end
|
43
48
|
end
|
44
49
|
end
|
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.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement: &
|
16
|
+
requirement: &16305120 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,8 +21,8 @@ dependencies:
|
|
21
21
|
version: 3.1.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
-
description: Enumerated attributes with I18n and ActiveRecord support
|
24
|
+
version_requirements: *16305120
|
25
|
+
description: Enumerated attributes with I18n and ActiveRecord/Mongoid support
|
26
26
|
email: info@twinslash.com
|
27
27
|
executables: []
|
28
28
|
extensions: []
|
@@ -36,17 +36,23 @@ files:
|
|
36
36
|
- README.md
|
37
37
|
- Rakefile
|
38
38
|
- enumerize.gemspec
|
39
|
+
- gemfiles/Gemfile-ar-3.1.x
|
39
40
|
- lib/enumerize.rb
|
41
|
+
- lib/enumerize/activerecord.rb
|
40
42
|
- lib/enumerize/attribute.rb
|
41
|
-
- lib/enumerize/
|
42
|
-
- lib/enumerize/
|
43
|
-
- lib/enumerize/
|
43
|
+
- lib/enumerize/base.rb
|
44
|
+
- lib/enumerize/hooks/formtastic.rb
|
45
|
+
- lib/enumerize/hooks/simple_form.rb
|
44
46
|
- lib/enumerize/value.rb
|
45
47
|
- lib/enumerize/version.rb
|
46
48
|
- test/activerecord_test.rb
|
47
49
|
- test/attribute_test.rb
|
48
|
-
- test/
|
50
|
+
- test/base_test.rb
|
51
|
+
- test/formtastic_test.rb
|
49
52
|
- test/mongoid_test.rb
|
53
|
+
- test/simple_form_test.rb
|
54
|
+
- test/support/mock_controller.rb
|
55
|
+
- test/support/view_test_helper.rb
|
50
56
|
- test/test_helper.rb
|
51
57
|
- test/value_test.rb
|
52
58
|
homepage: https://github.com/twinslash/enumerize
|
@@ -63,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
69
|
version: '0'
|
64
70
|
segments:
|
65
71
|
- 0
|
66
|
-
hash:
|
72
|
+
hash: 2845760837135079832
|
67
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
74
|
none: false
|
69
75
|
requirements:
|
@@ -72,17 +78,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
78
|
version: '0'
|
73
79
|
segments:
|
74
80
|
- 0
|
75
|
-
hash:
|
81
|
+
hash: 2845760837135079832
|
76
82
|
requirements: []
|
77
83
|
rubyforge_project:
|
78
|
-
rubygems_version: 1.8.
|
84
|
+
rubygems_version: 1.8.11
|
79
85
|
signing_key:
|
80
86
|
specification_version: 3
|
81
|
-
summary: Enumerated attributes with I18n and ActiveRecord support
|
87
|
+
summary: Enumerated attributes with I18n and ActiveRecord/Mongoid support
|
82
88
|
test_files:
|
83
89
|
- test/activerecord_test.rb
|
84
90
|
- test/attribute_test.rb
|
85
|
-
- test/
|
91
|
+
- test/base_test.rb
|
92
|
+
- test/formtastic_test.rb
|
86
93
|
- test/mongoid_test.rb
|
94
|
+
- test/simple_form_test.rb
|
95
|
+
- test/support/mock_controller.rb
|
96
|
+
- test/support/view_test_helper.rb
|
87
97
|
- test/test_helper.rb
|
88
98
|
- test/value_test.rb
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
|
3
|
-
module Enumerize
|
4
|
-
module Integrations
|
5
|
-
module Basic
|
6
|
-
extend ActiveSupport::Concern
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
def enumerize(*args, &block)
|
10
|
-
attr = Attribute.new(self, *args, &block)
|
11
|
-
singleton_class.class_eval do
|
12
|
-
define_method(attr.name) { attr }
|
13
|
-
end
|
14
|
-
|
15
|
-
mod = Module.new
|
16
|
-
|
17
|
-
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
18
|
-
def initialize(*, &_)
|
19
|
-
super
|
20
|
-
self.#{attr.name} = self.class.#{attr.name}.default_value if #{attr.name}.nil?
|
21
|
-
end
|
22
|
-
RUBY
|
23
|
-
|
24
|
-
_define_enumerize_attribute(mod, attr)
|
25
|
-
|
26
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
27
|
-
def #{attr.name}_text
|
28
|
-
#{attr.name} && #{attr.name}.text
|
29
|
-
end
|
30
|
-
RUBY
|
31
|
-
|
32
|
-
include mod
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def _define_enumerize_attribute(mod, attr)
|
38
|
-
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
39
|
-
def #{attr.name}
|
40
|
-
if respond_to?(:read_attribute, true)
|
41
|
-
self.class.#{attr.name}.find_value(read_attribute(:#{attr.name}))
|
42
|
-
else
|
43
|
-
if defined?(@#{attr.name})
|
44
|
-
self.class.#{attr.name}.find_value(@#{attr.name})
|
45
|
-
else
|
46
|
-
@#{attr.name} = nil
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def #{attr.name}=(new_value)
|
52
|
-
if respond_to?(:write_attribute, true)
|
53
|
-
write_attribute :#{attr.name}, self.class.#{attr.name}.find_value(new_value).to_s
|
54
|
-
else
|
55
|
-
@#{attr.name} = self.class.#{attr.name}.find_value(new_value).to_s
|
56
|
-
end
|
57
|
-
end
|
58
|
-
RUBY
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/test/basic_test.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
describe Enumerize::Integrations::Basic do
|
4
|
-
let(:klass) do
|
5
|
-
Class.new do
|
6
|
-
include Enumerize
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:object) { klass.new }
|
11
|
-
|
12
|
-
it 'returns nil when not set' do
|
13
|
-
klass.enumerize(:foo, :in => [:a, :b])
|
14
|
-
object.foo.must_equal nil
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'returns value that was set' do
|
18
|
-
klass.enumerize(:foo, :in => [:a, :b])
|
19
|
-
object.foo = :a
|
20
|
-
object.foo.must_equal 'a'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'returns translation' do
|
24
|
-
I18n.backend.store_translations(:en, :enumerize => {:foo => {:a => 'a text'}})
|
25
|
-
klass.enumerize(:foo, :in => [:a, :b])
|
26
|
-
object.foo = :a
|
27
|
-
object.foo.text.must_equal 'a text'
|
28
|
-
object.foo_text.must_equal 'a text'
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns nil as translation when value is nil' do
|
32
|
-
I18n.backend.store_translations(:en, :enumerize => {:foo => {:a => 'a text'}})
|
33
|
-
klass.enumerize(:foo, :in => [:a, :b])
|
34
|
-
object.foo_text.must_equal nil
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'scopes translation by i18 key' do
|
38
|
-
I18n.backend.store_translations(:en, :enumerize => {:example_class => {:foo => {:a => 'a text scoped'}}})
|
39
|
-
def klass.model_name
|
40
|
-
name = "ExampleClass"
|
41
|
-
def name.i18n_key
|
42
|
-
'example_class'
|
43
|
-
end
|
44
|
-
|
45
|
-
name
|
46
|
-
end
|
47
|
-
klass.enumerize(:foo, :in => [:a, :b])
|
48
|
-
object.foo = :a
|
49
|
-
object.foo.text.must_equal 'a text scoped'
|
50
|
-
object.foo_text.must_equal 'a text scoped'
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'stores value as string' do
|
54
|
-
klass.enumerize(:foo, :in => [:a, :b])
|
55
|
-
object.foo = :a
|
56
|
-
object.instance_variable_get(:@foo).must_be_instance_of String
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'handles default value' do
|
60
|
-
klass.enumerize(:foo, :in => [:a, :b], :default => :b)
|
61
|
-
object.foo.must_equal 'b'
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'raises exception on invalid default value' do
|
65
|
-
proc {
|
66
|
-
klass.enumerize(:foo, :in => [:a, :b], :default => :c)
|
67
|
-
}.must_raise ArgumentError
|
68
|
-
end
|
69
|
-
end
|