enumerize 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -9,7 +9,6 @@ gemfile:
9
9
  rvm:
10
10
  - 1.9.3
11
11
  - 2.0.0
12
- - ruby-head
13
12
  - jruby-19mode
14
13
  - rbx-19mode
15
14
  matrix:
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 'activerecord', '~> 3.2.0'
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 'activerecord', '4.0.0.rc1'
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 'simple_form', '3.0.0.beta1'
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 [![TravisCI](https://secure.travis-ci.org/brainspec/enumerize.png?branch=master)](http://travis-ci.org/brainspec/enumerize) [![Gemnasium](https://gemnasium.com/brainspec/enumerize.png)](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
- scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
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
- where(name => values)
17
- end
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
- if options[:scope] == true
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
@@ -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 = find_value(options[:default])
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
@@ -1,5 +1,7 @@
1
1
  module Enumerize
2
2
  class AttributeMap
3
+ attr_reader :attributes
4
+
3
5
  def initialize
4
6
  @attributes = {}
5
7
  @dependants = []
@@ -1,12 +1,10 @@
1
- require 'active_support/concern'
2
-
3
1
  module Enumerize
4
2
  module Base
5
- extend ActiveSupport::Concern
3
+ def self.included(base)
4
+ base.extend ClassMethods
6
5
 
7
- included do
8
- if respond_to?(:validate)
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
- self.class.enumerized_attributes.each do |attr|
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
@@ -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 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
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
- end
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
@@ -1,3 +1,3 @@
1
1
  module Enumerize
2
- VERSION = "0.6.1"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -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 'returns stores hash values' do
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
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'rails'
2
3
 
3
4
  module Formtastic
4
5
  module Helpers
@@ -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
@@ -18,7 +18,7 @@ describe Enumerize do
18
18
  field :sex
19
19
  field :role
20
20
  enumerize :sex, :in => %w[male female]
21
- enumerize :role, :in => %w[admine user], :default => 'user'
21
+ enumerize :role, :in => %w[admin user], :default => 'user'
22
22
  end
23
23
 
24
24
  before { $VERBOSE = nil }
@@ -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
@@ -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
@@ -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
@@ -1,5 +1,6 @@
1
1
  require 'test_helper'
2
2
  require 'simple_form/version'
3
+ require 'rails'
3
4
 
4
5
  class SimpleFormSpec < MiniTest::Spec
5
6
  include ViewTestHelper
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.6.1
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-05-20 00:00:00.000000000 Z
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 support
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: 2431695080895268301
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: []