mcommons-enum_for 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/enum_for.gemspec +1 -1
- data/lib/enum_for.rb +15 -3
- data/spec/enum_for_spec.rb +65 -44
- metadata +1 -1
data/enum_for.gemspec
CHANGED
data/lib/enum_for.rb
CHANGED
@@ -17,13 +17,20 @@ module EnumFor
|
|
17
17
|
attribute = args.first
|
18
18
|
|
19
19
|
plural_attribute = attribute.to_s.pluralize
|
20
|
-
|
20
|
+
|
21
|
+
# Accept both symbol and string forms for setting. They'll both be saved as strings in the DB anyway,
|
22
|
+
# so no need to accept only one form in the validation.
|
23
|
+
all_valid_values = options[:has].map{|v| v.to_s} | options[:has].map{|v| v.to_sym}
|
24
|
+
|
25
|
+
validates_inclusion_of attribute, options.except(:has, :prefix).merge(:in => all_valid_values )
|
21
26
|
const_set(plural_attribute.upcase, options[:has])
|
22
27
|
|
23
28
|
prefix = options.has_key?(:prefix) ? options[:prefix] : attribute.to_s
|
24
29
|
|
25
|
-
prefixed_values = options[:has].
|
26
|
-
|
30
|
+
prefixed_values = options[:has].inject({}) do |res, elem|
|
31
|
+
res.merge( [prefix, elem].compact.join('_') => elem.to_sym )
|
32
|
+
end
|
33
|
+
|
27
34
|
prefixed_values.each do |pv, v|
|
28
35
|
# Set constants for values
|
29
36
|
const_set(pv.upcase, v)
|
@@ -39,6 +46,11 @@ module EnumFor
|
|
39
46
|
end
|
40
47
|
end
|
41
48
|
|
49
|
+
# Attributes returned are cast as Symbols from their VARCHAR representation in the DB.
|
50
|
+
define_method(attribute.to_s) do
|
51
|
+
self[attribute].to_sym unless self[attribute].nil?
|
52
|
+
end
|
53
|
+
|
42
54
|
# Define a custom setter method which casts input to a String. Since we present the configuration
|
43
55
|
# of enum_fu using Symbols, this makes sense to provide to the user.
|
44
56
|
define_method("#{attribute}=") do |other|
|
data/spec/enum_for_spec.rb
CHANGED
@@ -27,62 +27,83 @@ describe EnumFor do
|
|
27
27
|
@taco = Taco.new(:state => 'new')
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
it "should return all possible states when plural of attribute is called as class method" do
|
51
|
-
Taco.states.should == [ :new, :composed, :served, :eaten ]
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should define constants for each type" do
|
55
|
-
Taco::STATE_EATEN.should == :eaten
|
30
|
+
describe "model validation" do
|
31
|
+
it "should make a valid model when given a valid state" do
|
32
|
+
@taco.should be_valid
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should retrieve a symbol when the model is created with attribute set to string" do
|
36
|
+
@taco.state.should == :new
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be valid when an attribute is set to a valid symbol" do
|
40
|
+
Taco.new(:state => :composed).should be_valid
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not be valid when an attribute is set to an invalid symbol" do
|
44
|
+
Taco.new(:state => :bogus).should_not be_valid
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not create a valid model when given an invalid state" do
|
48
|
+
Taco.create(:state => 'barfed').should_not be_valid
|
49
|
+
end
|
56
50
|
end
|
57
51
|
|
58
|
-
|
59
|
-
|
60
|
-
|
52
|
+
describe "storage and retrieval of possible states in class" do
|
53
|
+
it "should return all possible states when plural of the attribute is called as constant" do
|
54
|
+
Taco::STATES.should == [ :new, :composed, :served, :eaten ]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return all possible states when plural of attribute is called as class method" do
|
58
|
+
Taco.states.should == [ :new, :composed, :served, :eaten ]
|
59
|
+
end
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
it "should define constants for each type" do
|
62
|
+
Taco::STATE_EATEN.should == :eaten
|
63
|
+
end
|
65
64
|
end
|
66
65
|
|
67
|
-
|
68
|
-
|
66
|
+
describe "definition of predicate methods" do
|
67
|
+
it "should define predicate methods for each valid state" do
|
68
|
+
@taco.should respond_to(:state_eaten?)
|
69
|
+
end
|
69
70
|
end
|
70
|
-
|
71
|
-
|
72
|
-
Food
|
71
|
+
|
72
|
+
describe "with prefix option" do
|
73
|
+
class Food < ActiveRecord::Base
|
74
|
+
set_table_name "tacos"
|
75
|
+
enum_for :state, :has => [:stuff, :morestuff], :prefix => nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not prefix predicate methods if asked not to" do
|
79
|
+
Food.new(:state => :stuff).should respond_to(:stuff?)
|
80
|
+
end
|
73
81
|
end
|
74
82
|
|
75
|
-
|
76
|
-
|
77
|
-
|
83
|
+
describe "casting of values set and retrieved to correct type" do
|
84
|
+
it "should allow strings for attribute values even when initialized with symbols" do
|
85
|
+
Food.new(:state => 'stuff').should be_valid
|
86
|
+
end
|
78
87
|
|
79
|
-
|
80
|
-
|
88
|
+
it "should retrieve a symbol when a string is set and the attribute value is a symbol" do
|
89
|
+
f = Food.new(:state => 'stuff')
|
90
|
+
f.state.should == :stuff
|
81
91
|
end
|
82
92
|
end
|
83
93
|
|
84
|
-
|
85
|
-
Balloon
|
94
|
+
describe "behavior with existing methods of same name" do
|
95
|
+
class Balloon < ActiveRecord::Base
|
96
|
+
set_table_name "tacos"
|
97
|
+
enum_for :state, :has => [:stuff, :morestuff], :prefix => nil
|
98
|
+
|
99
|
+
def stuff?
|
100
|
+
"not a boolean"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should not define a predicate method when a one already exists" do
|
105
|
+
Balloon.new(:state => :stuff).stuff?.should == "not a boolean"
|
106
|
+
end
|
86
107
|
end
|
87
108
|
|
88
109
|
describe "with validation options" do
|