has_constant 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc CHANGED
@@ -1,2 +1,3 @@
1
+ rvm_gemset_create_on_use_flag=1
1
2
  rvm use 1.8.7
2
3
  rvm gemset use has_constant
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.6.0
data/has_constant.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{has_constant}
8
- s.version = "0.5.1"
8
+ s.version = "0.6.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["mattbeedle"]
@@ -28,12 +28,10 @@ Gem::Specification.new do |s|
28
28
  "has_constant.gemspec",
29
29
  "lib/has_constant.rb",
30
30
  "lib/has_constant/orm/active_model.rb",
31
- "lib/has_constant/orm/active_record.rb",
32
31
  "lib/has_constant/orm/mongoid.rb",
33
32
  "test/has_constant_test.rb",
34
33
  "test/helper.rb",
35
34
  "test/unit/orm/active_model_test.rb",
36
- "test/unit/orm/active_record_test.rb",
37
35
  "test/unit/orm/mongoid_test.rb"
38
36
  ]
39
37
  s.homepage = %q{http://github.com/mattbeedle/has_constant}
@@ -44,7 +42,6 @@ Gem::Specification.new do |s|
44
42
  "test/has_constant_test.rb",
45
43
  "test/helper.rb",
46
44
  "test/unit/orm/active_model_test.rb",
47
- "test/unit/orm/active_record_test.rb",
48
45
  "test/unit/orm/mongoid_test.rb"
49
46
  ]
50
47
 
@@ -13,13 +13,19 @@ module HasConstant
13
13
  # the stored value
14
14
  define_method(singular) do
15
15
  if read_attribute(singular)
16
- self.class.send(name)[read_attribute(singular).to_i]
16
+ if values.is_a?(Array)
17
+ self.class.send(name)[read_attribute(singular).to_i]
18
+ elsif values.is_a?(Hash)
19
+ self.class.send(name)[read_attribute(singular)]
20
+ end
17
21
  end
18
22
  end
19
23
 
20
24
  define_method("#{singular}=") do |val|
21
- if val.instance_of?(String)
25
+ if values.is_a?(Array) && val.instance_of?(String)
22
26
  write_attribute singular.to_sym, self.class.send(name.to_s).index(val)
27
+ elsif values.is_a?(Hash) && values.has_value?(val)
28
+ write_attribute singular.to_sym, values.invert[val].to_s
23
29
  else
24
30
  write_attribute singular.to_sym, val
25
31
  end
@@ -23,7 +23,7 @@ module HasConstant
23
23
 
24
24
  class_eval do
25
25
  unless fields.map(&:first).include?(singular.to_s)
26
- field singular.to_sym, { :type => Integer }.merge(options)
26
+ field singular.to_sym, { :type => values.is_a?(Array) ? Integer : String }.merge(options)
27
27
  end
28
28
 
29
29
  index singular.to_sym, :background => true if options[:index]
@@ -34,8 +34,10 @@ module HasConstant
34
34
 
35
35
  define_method("#{singular}=") do |val|
36
36
  if val.instance_of?(String)
37
- if index = self.class.send(name.to_s).index(val)
37
+ if values.is_a?(Array) && index = self.class.send(name.to_s).index(val)
38
38
  write_attribute singular.to_sym, index
39
+ elsif values.is_a?(Hash) && values.has_value?(val)
40
+ write_attribute singular.to_sym, values.invert[val]
39
41
  elsif !val.blank?
40
42
  values = values.call if values.respond_to?(:call)
41
43
  @has_constant_errors ||= {}
@@ -48,7 +50,11 @@ module HasConstant
48
50
 
49
51
  # Add the getter method. This returns the string representation of the stored value
50
52
  define_method(singular) do
51
- eval("#{self.class}.#{name.to_s}[self.attributes[singular].to_i] if self.attributes[singular]")
53
+ if values.is_a?(Array)
54
+ self.class.send(name.to_s)[attributes[singular].to_i] if attributes[singular]
55
+ else
56
+ self.class.send(name.to_s)[attributes[singular]] if attributes[singular]
57
+ end
52
58
  end
53
59
 
54
60
  (class << self; self; end).instance_eval do
data/lib/has_constant.rb CHANGED
@@ -42,6 +42,7 @@ module HasConstant
42
42
  singular = (options[:accessor] || name.to_s.singularize).to_s
43
43
 
44
44
  (class << self; self; end).instance_eval do
45
+ values = HashWithIndifferentAccess.new(values) if values.is_a?(Hash)
45
46
  define_method(name.to_s, values) if values.respond_to?(:call)
46
47
  define_method(name.to_s, lambda { values }) unless values.respond_to?(:call)
47
48
  end
@@ -53,8 +54,10 @@ module HasConstant
53
54
  # Add the setter method. This takes the string representation and converts it to an integer to store in the DB
54
55
  define_method("#{singular}=") do |val|
55
56
  if val.instance_of?(String)
56
- if values.index(val)
57
+ if values.is_a?(Array) && values.index(val)
57
58
  instance_variable_set("@#{singular}", values.index(val))
59
+ elsif values.is_a?(Hash) && values.has_value?(val)
60
+ instance_variable_set("@#{singular}", values.invert[val].to_s)
58
61
  else
59
62
  raise ArgumentError, "value for #{singular} must be in #{self.class.send(name.to_s).join(', ')}"
60
63
  end
@@ -7,6 +7,13 @@ end
7
7
 
8
8
  class TestHasConstant < Test::Unit::TestCase
9
9
 
10
+ should 'be able to store values in a hash' do
11
+ Model.has_constant :salutations, { :first => 'Mr', :second => 'Mrs' }
12
+ m = Model.new
13
+ m.salutation = 'Mr'
14
+ assert m.instance_variable_get("@salutation") == 'first'
15
+ end
16
+
10
17
  should 'default values to translated values list' do
11
18
  I18n.stubs(:t).returns(['a', 'b'])
12
19
  Model.has_constant :titles
data/test/helper.rb CHANGED
@@ -35,6 +35,9 @@ def connect_active_record
35
35
  create_table :users, :force => true do |t|
36
36
  t.integer :salutation
37
37
  end
38
+ create_table :things, :force => true do |t|
39
+ t.string :salutation
40
+ end
38
41
  end
39
42
  end
40
43
 
@@ -7,8 +7,27 @@ class User < ActiveRecord::Base
7
7
  include HasConstant
8
8
  end
9
9
 
10
+ class Thing < ActiveRecord::Base
11
+ include HasConstant
12
+ end
13
+
10
14
  class ActiveModelTest < Test::Unit::TestCase
11
15
  context 'Instance' do
16
+ context 'using a hash' do
17
+ setup do
18
+ Thing.has_constant :salutations, { :first => 'Mr', :second => 'Mrs' }
19
+ @u = Thing.new :salutation => 'Mrs'
20
+ end
21
+
22
+ should 'store the hash key' do
23
+ assert_equal 'second', @u.attributes['salutation']
24
+ end
25
+
26
+ should 'return the correct value' do
27
+ assert_equal 'Mrs', @u.salutation
28
+ end
29
+ end
30
+
12
31
  should 'save values as integers' do
13
32
  User.has_constant :salutations, %w(Mr Mrs)
14
33
  u = User.new(:salutation => 'Mr')
@@ -6,58 +6,71 @@ setup_mongoid
6
6
  class MongoUser
7
7
  include Mongoid::Document
8
8
  include HasConstant
9
-
10
- has_constant :salutations, ['Mr', 'Mrs']
11
9
  end if defined?(Mongoid)
12
10
 
13
- class MongoUserWithProc
11
+ class MongoUser2
14
12
  include Mongoid::Document
15
13
  include HasConstant
16
-
17
- has_constant :salutations, lambda { ['Mr', 'Mrs'] }
18
14
  end if defined?(Mongoid)
19
15
 
20
- class MongoUserWithout
16
+ class MongoUserWithHash
21
17
  include Mongoid::Document
22
18
  include HasConstant
23
- end
19
+ end if defined?(Mongoid)
24
20
 
25
21
  class MongoidTest < Test::Unit::TestCase
26
22
  context 'Instance' do
23
+
24
+ context 'using a hash' do
25
+ setup do
26
+ MongoUserWithHash.has_constant :salutations, { :first => 'Mr', :second => 'Mrs' }
27
+ @m = MongoUserWithHash.new(:salutation => 'Mr')
28
+ end
29
+
30
+ should 'store the hash key' do
31
+ assert_equal 'first', @m.attributes['salutation']
32
+ end
33
+
34
+ should 'return the correct value' do
35
+ assert_equal 'Mr', @m.salutation
36
+ end
37
+ end
38
+
27
39
  should 'add the field automatically' do
28
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs']
29
- assert MongoUserWithout.fields.map(&:first).include?('salutation')
40
+ MongoUser.has_constant :salutations, ['Mr', 'Mrs']
41
+ assert MongoUser.fields.map(&:first).include?('salutation')
30
42
  end
31
43
 
32
44
  should 'not add the field if it is already there' do
33
- MongoUserWithout.send(:field, :salutation, :type => Integer, :default => 0)
34
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs']
35
- assert_equal 'Mr', MongoUserWithout.new.salutation
45
+ MongoUser.send(:field, :salutation, :type => Integer, :default => 0)
46
+ MongoUser.has_constant :salutations, ['Mr', 'Mrs']
47
+ assert_equal 'Mr', MongoUser.new.salutation
36
48
  end
37
49
 
38
50
  should 'take the accessor into account when adding the field' do
39
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs'], :accessor => :sal
40
- assert MongoUserWithout.fields.map(&:first).include?('sal')
51
+ MongoUser.has_constant :salutations, ['Mr', 'Mrs'], :accessor => :sal
52
+ assert MongoUser.fields.map(&:first).include?('sal')
41
53
  end
42
54
 
43
55
  should 'default values to translated values list' do
44
56
  I18n.stubs(:t).returns(['a', 'b'])
45
- MongoUserWithout.has_constant :titles
46
- assert_equal ['a', 'b'], MongoUserWithout.titles
57
+ MongoUser.has_constant :titles
58
+ assert_equal ['a', 'b'], MongoUser.titles
47
59
  end
48
60
 
49
61
  should 'add index when index option is supplied' do
50
- MongoUserWithout.has_constant :salutations, ['Mr', 'Mrs'], :index => true
51
- MongoUserWithout.create_indexes
52
- assert MongoUserWithout.index_information.keys.any? { |key| key.match(/salutation/) }
62
+ MongoUser.has_constant :salutations, ['Mr', 'Mrs'], :index => true
63
+ MongoUser.create_indexes
64
+ assert MongoUser.index_information.keys.any? { |key| key.match(/salutation/) }
53
65
  end
54
66
 
55
67
  should 'not index when index option is not supplied' do
56
- MongoUser.create_indexes
57
- assert !MongoUser.index_information.keys.any? { |key| key.match(/salutation/) }
68
+ MongoUser2.create_indexes
69
+ assert !MongoUser2.index_information.keys.any? { |key| key.match(/salutation/) }
58
70
  end
59
71
 
60
72
  should 'save values as integers' do
73
+ MongoUser.has_constant :salutations, %w(Mr Mrs)
61
74
  m = MongoUser.new(:salutation => 'Mr')
62
75
  m.save!
63
76
  assert_equal 'Mr', m.salutation
@@ -65,25 +78,29 @@ class MongoidTest < Test::Unit::TestCase
65
78
  end
66
79
 
67
80
  should 'not be valid when an incorrect value is supplied' do
81
+ MongoUser.has_constant :salutations, %w(Mr Mrs)
68
82
  m = MongoUser.new(:salutation => 'asefe')
69
83
  assert !m.valid?
70
84
  assert_equal ['must be one of Mr, Mrs'], m.errors[:salutation]
71
85
  end
72
86
 
73
87
  should 'not be valid with an incorrect value is supplied and a proc/lambda has been used' do
74
- m = MongoUserWithProc.new(:salutation => 'asefe')
88
+ MongoUser.has_constant :salutations, Proc.new { %w(Mr Mrs) }
89
+ m = MongoUser.new(:salutation => 'asefe')
75
90
  assert !m.valid?
76
91
  assert_equal ['must be one of Mr, Mrs'], m.errors[:salutation]
77
92
  end
78
93
 
79
94
  should 'be valid when a blank value is supplied' do
80
- m = MongoUserWithProc.new(:salutation => '')
95
+ MongoUser.has_constant :salutations, Proc.new { %w(Mr Mrs) }
96
+ m = MongoUser.new(:salutation => '')
81
97
  assert m.valid?
82
98
  end
83
99
  end
84
100
 
85
101
  context 'Named Scopes' do
86
102
  setup do
103
+ MongoUser.has_constant :salutations, %w(Mr Mrs)
87
104
  @man = MongoUser.create!(:salutation => 'Mr')
88
105
  @woman = MongoUser.create!(:salutation => 'Mrs')
89
106
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_constant
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - mattbeedle
@@ -81,12 +81,10 @@ files:
81
81
  - has_constant.gemspec
82
82
  - lib/has_constant.rb
83
83
  - lib/has_constant/orm/active_model.rb
84
- - lib/has_constant/orm/active_record.rb
85
84
  - lib/has_constant/orm/mongoid.rb
86
85
  - test/has_constant_test.rb
87
86
  - test/helper.rb
88
87
  - test/unit/orm/active_model_test.rb
89
- - test/unit/orm/active_record_test.rb
90
88
  - test/unit/orm/mongoid_test.rb
91
89
  has_rdoc: true
92
90
  homepage: http://github.com/mattbeedle/has_constant
@@ -126,5 +124,4 @@ test_files:
126
124
  - test/has_constant_test.rb
127
125
  - test/helper.rb
128
126
  - test/unit/orm/active_model_test.rb
129
- - test/unit/orm/active_record_test.rb
130
127
  - test/unit/orm/mongoid_test.rb
@@ -1,65 +0,0 @@
1
- module HasConstant
2
- module Orm
3
- module ActiveRecord
4
- extend ActiveSupport::Concern
5
-
6
- module ClassMethods
7
- def has_constant( name, values, options = {} )
8
- super(name, values, options)
9
-
10
- singular = (options[:accessor] || name.to_s.singularize).to_s
11
-
12
- # Add the getter method. This returns the string representation of
13
- # the stored value
14
- define_method(singular) do
15
- if read_attribute(singular)
16
- self.class.send(name)[read_attribute(singular).to_i]
17
- end
18
- end
19
-
20
- define_method("#{singular}=") do |val|
21
- if val.instance_of?(String)
22
- write_attribute singular.to_sym, self.class.send(name.to_s).index(val)
23
- else
24
- write_attribute singular.to_sym, val
25
- end
26
- end
27
-
28
- class_eval do
29
- if respond_to?(:scope)
30
- scope :by_constant, lambda { |constant,value| { :conditions =>
31
- { constant.to_sym =>
32
- eval("#{self.to_s}.#{constant.pluralize}.index(value)") } } }
33
-
34
- scope "#{singular}_is".to_sym, lambda { |*values| { :conditions =>
35
- { singular.to_sym => indexes_for(name, values) }
36
- } }
37
-
38
- scope "#{singular}_is_not".to_sym, lambda { |*values| {
39
- :conditions => ["#{singular} NOT IN (?)",
40
- indexes_for(name, values)] } }
41
- else
42
- named_scope :by_constant, lambda { |constant,value| {
43
- :conditions =>
44
- { constant.to_sym =>
45
- eval("#{self.to_s}.#{constant.pluralize}.index(value)") } } }
46
-
47
- named_scope "#{singular}_is".to_sym, lambda { |*values| {
48
- :conditions => { singular.to_sym => indexes_for(name, values) }
49
- } }
50
-
51
- named_scope "#{singular}_is_not".to_sym, lambda { |*values| {
52
- :conditions => ["#{singular} NOT IN (?)",
53
- indexes_for(name, values)] } }
54
- end
55
- end
56
- end
57
-
58
- private
59
- def indexes_for( name, values )
60
- values.map { |v| self.send(name.to_sym).index(v) }
61
- end
62
- end
63
- end
64
- end
65
- end
@@ -1,40 +0,0 @@
1
- require 'helper'
2
-
3
- setup_active_record
4
-
5
- class User < ActiveRecord::Base
6
- include HasConstant
7
-
8
- has_constant :salutations, ['Mr', 'Mrs']
9
- end
10
-
11
- class ActiveRecordTest < Test::Unit::TestCase
12
- should 'save values as integers' do
13
- u = User.new(:salutation => 'Mr')
14
- u.save!
15
- assert_equal 'Mr', u.salutation
16
- assert_equal 0, u.attributes['salutation']
17
- end
18
-
19
- context 'scopes' do
20
- setup do
21
- @man = User.create!(:salutation => 'Mr')
22
- @woman = User.create!(:salutation => 'Mrs')
23
- end
24
-
25
- should 'provide by_constant scope' do
26
- assert_equal 1, User.by_constant('salutation', 'Mr').count
27
- assert_equal @man, User.by_constant('salutation', 'Mr').first
28
- end
29
-
30
- should 'provide singular_is scope' do
31
- assert_equal 1, User.salutation_is('Mr').count
32
- assert_equal @man, User.salutation_is('Mr').first
33
- end
34
-
35
- should 'provide singular_is_not scope' do
36
- assert_equal 1, User.salutation_is_not('Mr').count
37
- assert_equal @woman, User.salutation_is_not('Mr').first
38
- end
39
- end
40
- end if defined?(ActiveRecord)