enumerize 0.4.0 → 0.5.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 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