enumerize 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -5,6 +5,7 @@ before_install:
5
5
  - gem install bundler
6
6
  rvm:
7
7
  - 1.9.3
8
+ - ruby-head
8
9
  - jruby-19mode
9
10
  - rbx-19mode
10
11
  matrix:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.5.0 (October 31, 2012) ##
2
+
3
+ The previous method of adding enumerize to a class was deprecated. Please use
4
+ `extend Enumerize` instead of `include Enumerize`.
5
+
6
+ ### enhancements
7
+ * SimpleForm support for multiple attributes. (by [@nashby](https://github.com/nashby))
8
+ * Formtastic support for multiple attributes. (by [@nashby](https://github.com/nashby))
9
+ * Array-like multiple attributes. (by [@lest](https://github.com/lest))
10
+
1
11
  ## 0.4.0 (September 6, 2012) ##
2
12
 
3
13
  Legacy support was dropped. The following versions are supported:
@@ -8,7 +18,7 @@ Legacy support was dropped. The following versions are supported:
8
18
  * SimpleForm 2+
9
19
  * Mongoid 3+
10
20
 
11
- ### enchancements
21
+ ### enhancements
12
22
  * Ability to define predicate methods on enumerized object. (by [@lest](https://github.com/lest))
13
23
 
14
24
  ## 0.3.0 (July 9, 2012) ##
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'rake'
6
- gem 'minitest', '~> 3.1'
6
+ gem 'minitest', '~> 4.1'
7
7
 
8
8
  gem 'activerecord', '~> 3.2.0'
9
9
  gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
data/README.md CHANGED
@@ -22,7 +22,7 @@ Basic:
22
22
 
23
23
  ```ruby
24
24
  class User
25
- include Enumerize
25
+ extend Enumerize
26
26
 
27
27
  enumerize :sex, :in => [:male, :female]
28
28
  end
@@ -32,7 +32,7 @@ ActiveRecord:
32
32
 
33
33
  ```ruby
34
34
  class User < ActiveRecord::Base
35
- include Enumerize
35
+ extend Enumerize
36
36
 
37
37
  enumerize :sex, :in => [:male, :female]
38
38
 
@@ -45,7 +45,7 @@ Mongoid:
45
45
  ```ruby
46
46
  class User
47
47
  include Mongoid::Document
48
- include Enumerize
48
+ extend Enumerize
49
49
 
50
50
  field :role
51
51
  enumerize :role, :in => [:user, :admin], :default => :user
@@ -105,7 +105,8 @@ Predicate methods:
105
105
 
106
106
  ```ruby
107
107
  class User
108
- include Enumerize
108
+ extend Enumerize
109
+
109
110
  enumerize :sex, in: %w(male female), predicates: true
110
111
  end
111
112
 
@@ -124,7 +125,8 @@ Using prefix:
124
125
 
125
126
  ```ruby
126
127
  class User
127
- include Enumerize
128
+ extend Enumerize
129
+
128
130
  enumerize :sex, in: %w(male female), predicates: { prefix: true }
129
131
  end
130
132
 
@@ -138,7 +140,7 @@ To make some attributes shared across different classes it's possible to define
138
140
 
139
141
  ```ruby
140
142
  module PersonEnumerations
141
- include Enumerize
143
+ extend Enumerize
142
144
 
143
145
  enumerize :sex, :in => %w[male female]
144
146
  end
@@ -156,10 +158,37 @@ It's also possible to store enumerized attribute value using custom values (e.g.
156
158
 
157
159
  ```ruby
158
160
  class User < ActiveRecord::Base
161
+ extend Enumerize
162
+
159
163
  enumerize :role, :in => {:user => 1, :admin => 2}
160
164
  end
161
165
  ```
162
166
 
167
+ Array-like attributes with plain ruby objects:
168
+
169
+ ```ruby
170
+ class User
171
+ extend Enumerize
172
+
173
+ enumerize :interests, :in => [:music, :sports], :multiple => true
174
+ end
175
+
176
+ user = User.new
177
+ user.interests << :music
178
+ user.interests << :sports
179
+ ```
180
+
181
+ and with ActiveRecord:
182
+
183
+ ```ruby
184
+ class User < ActiveRecord::Base
185
+ extend Enumerize
186
+
187
+ serialize :interests, Array
188
+ enumerize :interests, :in => [:music, :sports], :multiple => true
189
+ end
190
+ ```
191
+
163
192
  ### SimpleForm
164
193
 
165
194
  If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
data/lib/enumerize.rb CHANGED
@@ -5,12 +5,18 @@ module Enumerize
5
5
  autoload :Attribute, 'enumerize/attribute'
6
6
  autoload :AttributeMap, 'enumerize/attribute_map'
7
7
  autoload :Value, 'enumerize/value'
8
+ autoload :Set, 'enumerize/set'
8
9
  autoload :Base, 'enumerize/base'
9
10
  autoload :ActiveRecord, 'enumerize/activerecord'
10
11
  autoload :Predicates, 'enumerize/predicates'
11
12
  autoload :ModuleAttributes, 'enumerize/module_attributes'
12
13
 
13
14
  def self.included(base)
15
+ ActiveSupport::Deprecation.warn '`include Enumerize` was deprecated. Please use `extend Enumerize`.', caller
16
+ extended(base)
17
+ end
18
+
19
+ def self.extended(base)
14
20
  base.send :include, Enumerize::Base
15
21
  base.extend Enumerize::Predicates
16
22
 
@@ -29,6 +35,7 @@ module Enumerize
29
35
  begin
30
36
  require 'simple_form'
31
37
  require 'enumerize/hooks/simple_form'
38
+ require 'enumerize/form_helper'
32
39
  rescue LoadError
33
40
  end
34
41
 
@@ -5,6 +5,8 @@ module Enumerize
5
5
  def initialize(klass, name, options={})
6
6
  raise ArgumentError, ':in option is required' unless options[:in]
7
7
 
8
+ extend Multiple if options[:multiple]
9
+
8
10
  @klass = klass
9
11
  @name = name.to_sym
10
12
  @values = Array(options[:in]).map { |v| Value.new(self, *v) }
@@ -28,5 +30,75 @@ module Enumerize
28
30
  def options
29
31
  @values.map { |v| [v.text, v.to_s] }
30
32
  end
33
+
34
+ def define_methods!(mod)
35
+ mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
36
+ def #{name}
37
+ if defined?(super)
38
+ self.class.enumerized_attributes[:#{name}].find_value(super)
39
+ else
40
+ if defined?(@#{name})
41
+ self.class.enumerized_attributes[:#{name}].find_value(@#{name})
42
+ else
43
+ @#{name} = nil
44
+ end
45
+ end
46
+ end
47
+
48
+ def #{name}=(new_value)
49
+ _enumerized_values_for_validation[:#{name}] = new_value.nil? ? nil : new_value.to_s
50
+
51
+ allowed_value_or_nil = self.class.enumerized_attributes[:#{name}].find_value(new_value)
52
+ allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
53
+
54
+ if defined?(super)
55
+ super allowed_value_or_nil
56
+ else
57
+ @#{name} = allowed_value_or_nil
58
+ end
59
+ end
60
+
61
+ def #{name}_text
62
+ self.#{name} && self.#{name}.text
63
+ end
64
+ RUBY
65
+ end
66
+ end
67
+
68
+ module Multiple
69
+ def define_methods!(mod)
70
+ mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
71
+ def #{name}
72
+ if defined?(@_#{name}_enumerized_set)
73
+ @_#{name}_enumerized_set
74
+ else
75
+ if defined?(super)
76
+ self.#{name} = super
77
+ else
78
+ if defined?(@#{name})
79
+ self.#{name} = @#{name}
80
+ else
81
+ self.#{name} = []
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ def #{name}=(values)
88
+ _enumerized_values_for_validation[:#{name}] = values.respond_to?(:map) ? values.map(&:to_s) : values
89
+
90
+ @_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
91
+ string_values = #{name}.values.map(&:to_str)
92
+
93
+ if defined?(super)
94
+ super string_values
95
+ else
96
+ @#{name} = string_values
97
+ end
98
+
99
+ #{name}
100
+ end
101
+ RUBY
102
+ end
31
103
  end
32
104
  end
@@ -4,6 +4,12 @@ module Enumerize
4
4
  module Base
5
5
  extend ActiveSupport::Concern
6
6
 
7
+ included do
8
+ if respond_to?(:validate)
9
+ validate :_validate_enumerized_attributes
10
+ end
11
+ end
12
+
7
13
  module ClassMethods
8
14
  def enumerize(name, options={})
9
15
  attr = Attribute.new(self, name, options)
@@ -17,17 +23,7 @@ module Enumerize
17
23
  RUBY
18
24
  end
19
25
 
20
- _define_enumerize_attribute(attr)
21
-
22
- _enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
23
- def #{attr.name}_text
24
- #{attr.name} && #{attr.name}.text
25
- end
26
- RUBY
27
-
28
- if respond_to?(:validates)
29
- validates name, :inclusion => { :in => enumerized_attributes[name].values, :allow_nil => true, :allow_blank => true }
30
- end
26
+ attr.define_methods!(_enumerize_module)
31
27
  end
32
28
 
33
29
  def enumerized_attributes
@@ -54,35 +50,6 @@ module Enumerize
54
50
  mod
55
51
  end
56
52
  end
57
-
58
- def _define_enumerize_attribute(attr)
59
- _enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
60
- def #{attr.name}
61
- if defined?(super)
62
- self.class.enumerized_attributes[:#{attr.name}].find_value(super)
63
- else
64
- if defined?(@#{attr.name})
65
- self.class.enumerized_attributes[:#{attr.name}].find_value(@#{attr.name})
66
- else
67
- @#{attr.name} = nil
68
- end
69
- end
70
- end
71
-
72
- def #{attr.name}=(new_value)
73
- _enumerized_values_for_validation[:#{attr.name}] = new_value.nil? ? nil : new_value.to_s
74
-
75
- allowed_value_or_nil = self.class.enumerized_attributes[:#{attr.name}].find_value(new_value)
76
- allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
77
-
78
- if defined?(super)
79
- super allowed_value_or_nil
80
- else
81
- @#{attr.name} = allowed_value_or_nil
82
- end
83
- end
84
- RUBY
85
- end
86
53
  end
87
54
 
88
55
  def initialize(*)
@@ -93,7 +60,7 @@ module Enumerize
93
60
  end
94
61
 
95
62
  def read_attribute_for_validation(key)
96
- if self.class.enumerized_attributes[key].instance_of?(Enumerize::Attribute) && _enumerized_values_for_validation.has_key?(key)
63
+ if _enumerized_values_for_validation.has_key?(key)
97
64
  _enumerized_values_for_validation[key]
98
65
  else
99
66
  super
@@ -105,5 +72,20 @@ module Enumerize
105
72
  def _enumerized_values_for_validation
106
73
  @_enumerized_values_for_validation ||= {}
107
74
  end
75
+
76
+ def _validate_enumerized_attributes
77
+ self.class.enumerized_attributes.each do |attr|
78
+ value = read_attribute_for_validation(attr.name)
79
+ next if value.blank?
80
+
81
+ allowed = attr.values
82
+
83
+ if attr.kind_of? Multiple
84
+ errors.add attr.name unless value.respond_to?(:all?) && value.all? { |v| v.blank? || allowed.include?(v) }
85
+ else
86
+ errors.add attr.name unless allowed.include?(value)
87
+ end
88
+ end
89
+ end
108
90
  end
109
91
  end
@@ -0,0 +1,27 @@
1
+ # backport of https://github.com/rails/rails/commit/3be9e8a0c2187744b6c9879ca2836cef5ebed693
2
+ module ActionView
3
+ module Helpers
4
+ module FormHelper
5
+ InstanceTag.class_eval do
6
+ def self.check_box_checked?(value, checked_value)
7
+ case value
8
+ when TrueClass, FalseClass
9
+ value
10
+ when NilClass
11
+ false
12
+ when Integer
13
+ value != 0
14
+ when String
15
+ value == checked_value
16
+ else
17
+ if value.respond_to?(:include?)
18
+ value.include?(checked_value)
19
+ else
20
+ value.to_i != 0
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -11,8 +11,13 @@ module Enumerize
11
11
 
12
12
  def input_with_enumerize(method, options={})
13
13
  klass = object.class
14
+
14
15
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
15
16
  options[:collection] ||= attr.options
17
+
18
+ if attr.kind_of?(Enumerize::Multiple) && options[:as] != :check_boxes
19
+ options[:input_html] = options.fetch(:input_html, {}).merge(:multiple => true)
20
+ end
16
21
  end
17
22
 
18
23
  input_without_enumerize(method, options)
@@ -11,8 +11,13 @@ module Enumerize
11
11
 
12
12
  def input_with_enumerize(attribute_name, options={}, &block)
13
13
  klass = object.class
14
+
14
15
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[attribute_name])
15
16
  options[:collection] ||= attr.options
17
+
18
+ if attr.kind_of?(Enumerize::Multiple) && options[:as] != :check_boxes
19
+ options[:input_html] = options.fetch(:input_html, {}).merge(:multiple => true)
20
+ end
16
21
  end
17
22
 
18
23
  input_without_enumerize(attribute_name, options, &block)
@@ -1,7 +1,7 @@
1
1
  module Enumerize
2
2
  module ModuleAttributes
3
3
  def included(base)
4
- base.send :include, Enumerize
4
+ base.extend Enumerize
5
5
  base.send :include, _enumerize_module
6
6
  base.extend _enumerize_module._class_methods
7
7
  enumerized_attributes.add_dependant base.enumerized_attributes
@@ -4,7 +4,7 @@ module Enumerize
4
4
  # Basic usage:
5
5
  #
6
6
  # class User
7
- # include Enumerize
7
+ # extend Enumerize
8
8
  # enumerize :sex, in: %w(male female), predicates: true
9
9
  # end
10
10
  #
@@ -21,7 +21,7 @@ module Enumerize
21
21
  # Using prefix:
22
22
  #
23
23
  # class User
24
- # include Enumerize
24
+ # extend Enumerize
25
25
  # enumerize :sex, in: %w(male female), predicates: { prefix: true }
26
26
  # end
27
27
  #
@@ -0,0 +1,60 @@
1
+ module Enumerize
2
+ class Set
3
+ include Enumerable
4
+
5
+ attr_reader :values
6
+
7
+ def initialize(obj, attr, values)
8
+ @obj = obj
9
+ @attr = attr
10
+ @values = ::Set.new
11
+
12
+ if values.respond_to?(:each)
13
+ values.each do |input|
14
+ value = @attr.find_value(input)
15
+ @values << value if value
16
+ end
17
+ end
18
+ end
19
+
20
+ def <<(value)
21
+ @values << value
22
+ mutate!
23
+ end
24
+
25
+ alias_method :push, :<<
26
+
27
+ delegate :each, :empty?, :size, to: :values
28
+
29
+ def to_ary
30
+ @values.to_a
31
+ end
32
+
33
+ delegate :join, to: :to_ary
34
+
35
+ def ==(other)
36
+ other.size == size && other.all? { |v| @values.include?(@attr.find_value(v)) }
37
+ end
38
+
39
+ alias_method :eql?, :==
40
+
41
+ def include?(value)
42
+ @values.include?(@attr.find_value(value))
43
+ end
44
+
45
+ def delete(value)
46
+ @values.delete(@attr.find_value(value))
47
+ mutate!
48
+ end
49
+
50
+ def inspect
51
+ "#<Enumerize::Set {#{join(', ')}}>"
52
+ end
53
+
54
+ private
55
+
56
+ def mutate!
57
+ @values = @obj.public_send("#{@attr.name}=", @values).values
58
+ end
59
+ end
60
+ end
@@ -1,3 +1,3 @@
1
1
  module Enumerize
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -13,15 +13,19 @@ ActiveRecord::Base.connection.instance_eval do
13
13
  t.string :sex
14
14
  t.string :role
15
15
  t.string :name
16
+ t.string :interests
16
17
  end
17
18
  end
18
19
 
19
20
  class User < ActiveRecord::Base
20
- include Enumerize
21
+ extend Enumerize
21
22
 
22
23
  enumerize :sex, :in => [:male, :female]
23
24
 
24
25
  enumerize :role, :in => [:user, :admin], :default => :user
26
+
27
+ serialize :interests, Array
28
+ enumerize :interests, :in => [:music, :sports, :dancing, :programming], :multiple => true
25
29
  end
26
30
 
27
31
  describe Enumerize::ActiveRecord do
@@ -82,4 +86,44 @@ describe Enumerize::ActiveRecord do
82
86
  user.role = ''
83
87
  user.read_attribute(:role).must_equal nil
84
88
  end
89
+
90
+ it 'supports multiple attributes' do
91
+ user = User.new
92
+ user.interests.must_be_empty
93
+ user.interests << :music
94
+ user.interests.must_equal %w(music)
95
+ user.save!
96
+
97
+ user = User.find(user.id)
98
+ user.interests.must_equal %w(music)
99
+ user.interests << :sports
100
+ user.interests.must_equal %w(music sports)
101
+
102
+ user.interests = []
103
+ interests = user.interests
104
+ interests << :music
105
+ interests.must_equal %w(music)
106
+ interests << :dancing
107
+ interests.must_equal %w(music dancing)
108
+ end
109
+
110
+ it 'returns invalid multiple value for validation' do
111
+ user = User.new
112
+ user.interests << :music
113
+ user.interests << :invalid
114
+ values = user.read_attribute_for_validation(:interests)
115
+ values.must_equal %w(music invalid)
116
+ end
117
+
118
+ it 'validates multiple attributes' do
119
+ user = User.new
120
+ user.interests << :invalid
121
+ user.wont_be :valid?
122
+
123
+ user.interests = Object.new
124
+ user.wont_be :valid?
125
+
126
+ user.interests = ['music', '']
127
+ user.must_be :valid?
128
+ end
85
129
  end
data/test/base_test.rb CHANGED
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  describe Enumerize::Base do
4
4
  let(:klass) do
5
5
  Class.new do
6
- include Enumerize
6
+ extend Enumerize
7
7
  end
8
8
  end
9
9
 
@@ -154,7 +154,7 @@ describe Enumerize::Base do
154
154
 
155
155
  klass = Class.new do
156
156
  include accessors
157
- include Enumerize
157
+ extend Enumerize
158
158
 
159
159
  enumerize :foo, :in => %w[test]
160
160
  end
@@ -15,11 +15,20 @@ class FormtasticSpec < MiniTest::Spec
15
15
  include ViewTestHelper
16
16
  include Formtastic::Helpers::FormHelper
17
17
 
18
+ class Thing < Struct.new(:name)
19
+ extend ActiveModel::Naming
20
+ include ActiveModel::Conversion
21
+
22
+ def persisted?
23
+ false
24
+ end
25
+ end
26
+
18
27
  class User < Struct.new(:sex, :age)
19
28
  extend ActiveModel::Naming
20
29
  include ActiveModel::Conversion
21
30
 
22
- include Enumerize
31
+ extend Enumerize
23
32
 
24
33
  enumerize :sex, :in => [:male, :female]
25
34
 
@@ -28,10 +37,24 @@ class FormtasticSpec < MiniTest::Spec
28
37
  end
29
38
  end
30
39
 
40
+ class Post < Struct.new(:category, :title)
41
+ extend ActiveModel::Naming
42
+ include ActiveModel::Conversion
43
+
44
+ extend Enumerize
45
+
46
+ enumerize :categories, :in => [:music, :games], :multiple => true
47
+
48
+ def persisted?
49
+ false
50
+ end
51
+ end
52
+
31
53
  before { $VERBOSE = nil }
32
54
  after { $VERBOSE = true }
33
55
 
34
56
  let(:user) { User.new }
57
+ let(:post) { Post.new }
35
58
 
36
59
  it 'renders select with enumerized values' do
37
60
  concat(semantic_form_for(user) do |f|
@@ -42,6 +65,49 @@ class FormtasticSpec < MiniTest::Spec
42
65
  assert_select 'select option[value=female]'
43
66
  end
44
67
 
68
+ it 'renders multiple select with enumerized values' do
69
+ concat(semantic_form_for(post) do |f|
70
+ f.input(:categories)
71
+ end)
72
+
73
+ assert_select 'select[multiple=multiple]'
74
+ assert_select 'select option[value=music]'
75
+ assert_select 'select option[value=games]'
76
+ end
77
+
78
+ it 'renders multiple select with selected enumerized value' do
79
+ post.categories << :music
80
+
81
+ concat(semantic_form_for(post) do |f|
82
+ f.input(:categories)
83
+ end)
84
+
85
+ assert_select 'select[multiple=multiple]'
86
+ assert_select 'select option[value=music][selected=selected]'
87
+ assert_select 'select option[value=games][selected=selected]', count: 0
88
+ end
89
+
90
+ it 'renders checkboxes with enumerized values' do
91
+ concat(semantic_form_for(post) do |f|
92
+ f.input(:categories, as: :check_boxes)
93
+ end)
94
+
95
+ assert_select 'select[multiple=multiple]', count: 0
96
+ assert_select 'input[type=checkbox][value=music]'
97
+ assert_select 'input[type=checkbox][value=games]'
98
+ end
99
+
100
+ it 'renders checkboxes with selected enumerized value' do
101
+ post.categories << :music
102
+
103
+ concat(semantic_form_for(post) do |f|
104
+ f.input(:categories, as: :check_boxes)
105
+ end)
106
+
107
+ assert_select 'input[type=checkbox][value=music][checked=checked]'
108
+ assert_select 'input[type=checkbox][value=games][checked=checked]', count: 0
109
+ end
110
+
45
111
  it 'renders radio buttons with enumerized values' do
46
112
  concat(semantic_form_for(user) do |f|
47
113
  f.input :sex, :as => :radio
@@ -58,4 +124,12 @@ class FormtasticSpec < MiniTest::Spec
58
124
 
59
125
  assert_select 'input[type=text]'
60
126
  end
127
+
128
+ it 'does not affect not enumerized classes' do
129
+ concat(semantic_form_for(Thing.new) do |f|
130
+ f.input(:name)
131
+ end)
132
+
133
+ assert_select 'input[type=text]'
134
+ end
61
135
  end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  class ModuleAttributesSpec < MiniTest::Spec
4
4
  it 'inherits attribute from the module' do
5
5
  mod = Module.new do
6
- include Enumerize
6
+ extend Enumerize
7
7
  enumerize :sex, :in => %w[male female], :default => 'male'
8
8
  end
9
9
 
@@ -16,7 +16,7 @@ class ModuleAttributesSpec < MiniTest::Spec
16
16
 
17
17
  it 'uses new attributes from the module' do
18
18
  mod = Module.new do
19
- include Enumerize
19
+ extend Enumerize
20
20
  end
21
21
 
22
22
  klass = Class.new
data/test/mongoid_test.rb CHANGED
@@ -13,7 +13,7 @@ end
13
13
  describe Enumerize do
14
14
  class MongoidUser
15
15
  include Mongoid::Document
16
- include Enumerize
16
+ extend Enumerize
17
17
 
18
18
  field :sex
19
19
  field :role
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ describe Enumerize::Base do
4
+ let(:klass) do
5
+ Class.new do
6
+ extend Enumerize
7
+ end
8
+ end
9
+
10
+ let(:subklass) do
11
+ Class.new(klass)
12
+ end
13
+
14
+ let(:object) { klass.new }
15
+
16
+ it 'returns [] when not set' do
17
+ klass.enumerize :foos, in: %w(a b), multiple: true
18
+ object.foos.must_equal []
19
+ end
20
+
21
+ it 'returns setted array' do
22
+ klass.enumerize :foos, in: %w(a b c), multiple: true
23
+ object.foos = %w(a c)
24
+ object.foos.must_equal %w(a c)
25
+ end
26
+
27
+ it "doesn't define _text method" do
28
+ klass.enumerize :foos, in: %w(a b c), multiple: true
29
+ object.wont_respond_to :foos_text
30
+ end
31
+ end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  describe Enumerize::Predicates do
4
4
  let(:klass) do
5
5
  Class.new do
6
- include Enumerize
6
+ extend Enumerize
7
7
  end
8
8
  end
9
9
 
data/test/set_test.rb ADDED
@@ -0,0 +1,112 @@
1
+ require 'test_helper'
2
+
3
+ describe Enumerize::Set do
4
+ let(:klass) do
5
+ Class.new do
6
+ extend Enumerize
7
+ enumerize :foo, :in => %w(a b c), :multiple => true
8
+ end
9
+ end
10
+
11
+ let(:object) { klass.new }
12
+
13
+ def build_set(values)
14
+ @set = Enumerize::Set.new(object, klass.foo, values)
15
+ end
16
+
17
+ def set
18
+ @set
19
+ end
20
+
21
+ def assert_called(object, method)
22
+ called = false
23
+
24
+ object.singleton_class.class_eval do
25
+ define_method method do |*args, &block|
26
+ called = true
27
+ super(*args, &block)
28
+ end
29
+ end
30
+
31
+ yield
32
+
33
+ assert called, "Expected ##{method} to be called"
34
+ end
35
+
36
+ before do
37
+ build_set %w(a)
38
+ end
39
+
40
+ it 'equals to other set' do
41
+ set.must_equal Enumerize::Set.new(nil, klass.foo, %w(a))
42
+ end
43
+
44
+ it 'equals to array' do
45
+ set.must_equal %w(a)
46
+ end
47
+
48
+ it 'equals to array of symbols' do
49
+ set.must_equal [:a]
50
+ end
51
+
52
+ it 'has unique values' do
53
+ set << :a
54
+ set.must_equal %w(a)
55
+ end
56
+
57
+ it 'equals to array with different value order' do
58
+ set << :b
59
+ set.must_equal %w(b a)
60
+ end
61
+
62
+ it "isn't equal to a part of values" do
63
+ set << :b
64
+ set.wont_equal %w(a)
65
+ end
66
+
67
+ describe '#push' do
68
+ it 'appends values' do
69
+ set.push :b
70
+ set.must_include :b
71
+ end
72
+
73
+ it 'reassigns attribute' do
74
+ assert_called object, :foo= do
75
+ set.push :b
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#delete' do
81
+ it 'deletes value' do
82
+ set.delete :a
83
+ set.wont_include :a
84
+ end
85
+
86
+ it 'reassigns attribute' do
87
+ assert_called object, :foo= do
88
+ set.delete :a
89
+ end
90
+ end
91
+ end
92
+
93
+ describe '#inspect' do
94
+ it 'returns custom string' do
95
+ set << :b
96
+ set.inspect.must_equal '#<Enumerize::Set {a, b}>'
97
+ end
98
+ end
99
+
100
+ describe '#to_ary' do
101
+ it 'returns array' do
102
+ set.to_ary.must_be_instance_of Array
103
+ end
104
+ end
105
+
106
+ describe '#join' do
107
+ it 'joins values' do
108
+ set << :b
109
+ set.join(', ').must_equal 'a, b'
110
+ end
111
+ end
112
+ end
@@ -5,11 +5,20 @@ class SimpleFormSpec < MiniTest::Spec
5
5
  include ViewTestHelper
6
6
  include SimpleForm::ActionViewExtensions::FormHelper
7
7
 
8
+ class Thing < Struct.new(:name)
9
+ extend ActiveModel::Naming
10
+ include ActiveModel::Conversion
11
+
12
+ def persisted?
13
+ false
14
+ end
15
+ end
16
+
8
17
  class User < Struct.new(:sex, :age)
9
18
  extend ActiveModel::Naming
10
19
  include ActiveModel::Conversion
11
20
 
12
- include Enumerize
21
+ extend Enumerize
13
22
 
14
23
  enumerize :sex, :in => [:male, :female]
15
24
 
@@ -18,7 +27,21 @@ class SimpleFormSpec < MiniTest::Spec
18
27
  end
19
28
  end
20
29
 
30
+ class Post < Struct.new(:category, :title)
31
+ extend ActiveModel::Naming
32
+ include ActiveModel::Conversion
33
+
34
+ extend Enumerize
35
+
36
+ enumerize :categories, :in => [:music, :games], :multiple => true
37
+
38
+ def persisted?
39
+ false
40
+ end
41
+ end
42
+
21
43
  let(:user) { User.new }
44
+ let(:post) { Post.new }
22
45
 
23
46
  it 'renders select with enumerized values' do
24
47
  concat(simple_form_for(user) do |f|
@@ -29,11 +52,52 @@ class SimpleFormSpec < MiniTest::Spec
29
52
  assert_select 'select option[value=female]'
30
53
  end
31
54
 
32
- it 'renders radio buttons with enumerated values' do
33
- as = SimpleForm::VERSION > '2.0' ? :radio_buttons : :radio
55
+ it 'renders multiple select with enumerized values' do
56
+ concat(simple_form_for(post) do |f|
57
+ f.input(:categories)
58
+ end)
59
+
60
+ assert_select 'select[multiple=multiple]'
61
+ assert_select 'select option[value=music]'
62
+ assert_select 'select option[value=games]'
63
+ end
64
+
65
+ it 'renders multiple select with selected enumerized value' do
66
+ post.categories << :music
67
+
68
+ concat(simple_form_for(post) do |f|
69
+ f.input(:categories)
70
+ end)
71
+
72
+ assert_select 'select[multiple=multiple]'
73
+ assert_select 'select option[value=music][selected=selected]'
74
+ assert_select 'select option[value=games][selected=selected]', count: 0
75
+ end
76
+
77
+ it 'renders checkboxes with enumerized values' do
78
+ concat(simple_form_for(post) do |f|
79
+ f.input(:categories, as: :check_boxes)
80
+ end)
81
+
82
+ assert_select 'select[multiple=multiple]', count: 0
83
+ assert_select 'input[type=checkbox][value=music]'
84
+ assert_select 'input[type=checkbox][value=games]'
85
+ end
86
+
87
+ it 'renders checkboxes with selected enumerized value' do
88
+ post.categories << :music
34
89
 
90
+ concat(simple_form_for(post) do |f|
91
+ f.input(:categories, as: :check_boxes)
92
+ end)
93
+
94
+ assert_select 'input[type=checkbox][value=music][checked=checked]'
95
+ assert_select 'input[type=checkbox][value=games][checked=checked]', count: 0
96
+ end
97
+
98
+ it 'renders radio buttons with enumerated values' do
35
99
  concat(simple_form_for(user) do |f|
36
- f.input(:sex, :as => as)
100
+ f.input(:sex, :as => :radio_buttons)
37
101
  end)
38
102
 
39
103
  assert_select 'input[type=radio][value=male]'
@@ -47,4 +111,12 @@ class SimpleFormSpec < MiniTest::Spec
47
111
 
48
112
  assert_select 'input.string'
49
113
  end
114
+
115
+ it 'does not affect not enumerized classes' do
116
+ concat(simple_form_for(Thing.new) do |f|
117
+ f.input(:name)
118
+ end)
119
+
120
+ assert_select 'input.string'
121
+ end
50
122
  end
metadata CHANGED
@@ -1,32 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: enumerize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
5
4
  prerelease:
5
+ version: 0.5.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sergey Nartimov
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-06 00:00:00.000000000 Z
12
+ date: 2012-10-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '3.2'
20
+ none: false
22
21
  type: :runtime
23
- prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '3.2'
27
+ none: false
28
+ prerelease: false
29
+ name: activesupport
30
30
  description: Enumerated attributes with I18n and ActiveRecord/Mongoid support
31
31
  email: team@brainspec.com
32
32
  executables: []
@@ -46,10 +46,12 @@ files:
46
46
  - lib/enumerize/attribute.rb
47
47
  - lib/enumerize/attribute_map.rb
48
48
  - lib/enumerize/base.rb
49
+ - lib/enumerize/form_helper.rb
49
50
  - lib/enumerize/hooks/formtastic.rb
50
51
  - lib/enumerize/hooks/simple_form.rb
51
52
  - lib/enumerize/module_attributes.rb
52
53
  - lib/enumerize/predicates.rb
54
+ - lib/enumerize/set.rb
53
55
  - lib/enumerize/value.rb
54
56
  - lib/enumerize/version.rb
55
57
  - test/activerecord_test.rb
@@ -59,7 +61,9 @@ files:
59
61
  - test/formtastic_test.rb
60
62
  - test/module_attributes_test.rb
61
63
  - test/mongoid_test.rb
64
+ - test/multiple_test.rb
62
65
  - test/predicates_test.rb
66
+ - test/set_test.rb
63
67
  - test/simple_form_test.rb
64
68
  - test/support/mock_controller.rb
65
69
  - test/support/view_test_helper.rb
@@ -72,23 +76,23 @@ rdoc_options: []
72
76
  require_paths:
73
77
  - lib
74
78
  required_ruby_version: !ruby/object:Gem::Requirement
75
- none: false
76
79
  requirements:
77
80
  - - ! '>='
78
81
  - !ruby/object:Gem::Version
82
+ hash: -4428159694445712973
79
83
  version: '0'
80
84
  segments:
81
85
  - 0
82
- hash: 1785538232513352876
83
- required_rubygems_version: !ruby/object:Gem::Requirement
84
86
  none: false
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
88
  requirements:
86
89
  - - ! '>='
87
90
  - !ruby/object:Gem::Version
91
+ hash: -4428159694445712973
88
92
  version: '0'
89
93
  segments:
90
94
  - 0
91
- hash: 1785538232513352876
95
+ none: false
92
96
  requirements: []
93
97
  rubyforge_project:
94
98
  rubygems_version: 1.8.23
@@ -103,7 +107,9 @@ test_files:
103
107
  - test/formtastic_test.rb
104
108
  - test/module_attributes_test.rb
105
109
  - test/mongoid_test.rb
110
+ - test/multiple_test.rb
106
111
  - test/predicates_test.rb
112
+ - test/set_test.rb
107
113
  - test/simple_form_test.rb
108
114
  - test/support/mock_controller.rb
109
115
  - test/support/view_test_helper.rb