classy_enum 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -16,66 +16,84 @@ h2. Example Usage
16
16
 
17
17
  The most common use for ClassyEnum is to replace database lookup tables where the content and behavior is mostly static and has multiple "types". In this example, I have an ActiveRecord model called @Alarm@ with an attribute called @priority@. Priority is stored as a string (VARCHAR) type in the database and is converted to an enum value when requested.
18
18
 
19
+ h3. 1. Generate the Enum
20
+
19
21
  The fastest way to get up and running with ClassyEnum is to use the built-in Rails generator like so:
20
22
 
21
23
  Rails 2.3.x:
22
24
 
23
25
  <pre>
24
- script/generate classy_enum AlarmPriority low medium high
26
+ script/generate classy_enum Priority low medium high
25
27
  </pre>
26
28
 
27
29
  Rails 3.x
28
30
 
29
31
  <pre>
30
- rails g classy_enum AlarmPriority low medium high
32
+ rails g classy_enum Priority low medium high
31
33
  </pre>
32
34
 
33
- A new file will be created at app/enums/alarm_priority.rb that will look like:
35
+ A new enum template file will be created at app/enums/priority.rb that will look like:
34
36
 
35
37
  <pre>
36
- class AlarmPriority < ClassyEnum::Base
38
+ class Priority < ClassyEnum::Base
37
39
  enum_classes :low, :medium, :high
38
40
  end
39
41
 
40
- class AlarmPriorityLow
42
+ class PriorityLow < Priority
41
43
  end
42
44
 
43
- class AlarmPriorityMedium
45
+ class PriorityMedium < Priority
44
46
  end
45
47
 
46
- class AlarmPriorityHigh
48
+ class PriorityHigh < Priority
47
49
  end
48
50
  </pre>
49
51
 
50
- That is the default setup, but can be changed to fit your needs, like so...
52
+ The @enum_classes@ macro will add all the ClassyEnum behavior, which is described further down in this document.
53
+
54
+ h3. 2. Customize the Enum
55
+
56
+ The generator creates a default setup, but each enum member can be changed to fit your needs.
51
57
 
52
- Using the @enum_classes@ method, I have defined three priority levels: low, medium, and high. Each priority level can have different properties and methods associated with it. In my example, each enum class has a method called @email?@. By default this method returns false, but is overridden for high priority alarms and returns true.
58
+ Using the @enum_classes@ method, I have defined three priority levels: low, medium, and high. Each priority level can have different properties and methods associated with it.
59
+
60
+ I would like to add a method called @send_email?@ that all member subclasses respond to. By default this method will return false, but will be overridden for high priority alarms to return true.
53
61
 
54
62
  <pre>
55
- class AlarmPriority < ClassyEnum::Base
63
+ class Priority < ClassyEnum::Base
56
64
  enum_classes :low, :medium, :high
57
-
58
- def email?
65
+
66
+ def send_email?
59
67
  false
60
68
  end
61
69
  end
62
70
 
63
- class AlarmPriorityHigh
64
- def email?
71
+ class PriorityHigh < Priority
72
+ def send_email?
65
73
  true
66
74
  end
67
75
  end
68
76
  </pre>
69
77
 
70
- Then in my ActiveRecord model, Alarm, I've added a line that calls @classy_enum_attr@. The first argument is required, and is the name of the class defined above. The second argument is optional and specifies which Alarm attribute will be used as an enumerable.
78
+ Note: Defining the subclasses within your enum file is only required when you will be overriding behavior and/or properties. The member subclasses still exist without being defined here because ClassyEnum.enum_classes automatically creates a class for each member. The generator only creates these subclass definitions for convenience, but they can be deleted as shown in this example.
79
+
80
+ h3. 3. Setup the ActiveRecord model
81
+
82
+ My ActiveRecord Alarm model needs a text field that will store a string representing the enum member. An example model schema might look something like:
83
+
84
+ <pre>
85
+ create_table "alarms", :force => true do |t|
86
+ t.string "priority"
87
+ end
88
+ </pre>
71
89
 
72
- In this case, I am using the class AlarmPriority, but the name of my attribute is priority. By default, it will use the name of class as the attribute name. If I wanted to do @alarm.alarm_priority@, I would not have included the second argument.
90
+ Then in my model I've added a line that calls @classy_enum_attr@ with a single argument representing the enum I want to associate with my model. I am also delegating the send_email? method to my Priority enum class.
73
91
 
74
92
  <pre>
75
93
  class Alarm < ActiveRecord::Base
76
- classy_enum_attr :alarm_priority, :priority
77
-
78
- delegate :email?, :to => :priority
94
+ classy_enum_attr :priority
95
+
96
+ delegate :send_email?, :to => :priority
79
97
  end
80
98
  </pre>
81
99
 
@@ -83,14 +101,64 @@ With this setup, I can now do the following:
83
101
 
84
102
  <pre>
85
103
  @alarm = Alarm.create(:priority => :medium)
86
-
87
- @alarm.priority => AlarmPriorityMedium
88
-
89
- @alarm.email? => false
90
-
91
- @alarm.update_attribute(:priority, :high)
92
-
93
- @alarm.email? => true
104
+
105
+ @alarm.priority # => PriorityMedium
106
+ @alarm.priority.is? :medium # => true
107
+ @alarm.priority.to_s # => 'medium'
108
+ @alarm.priority.name # => 'Medium'
109
+
110
+ # Should this alarm send an email?
111
+ @alarm.send_email? # => false
112
+ @alarm.priority = :high
113
+ @alarm.send_email? # => true
114
+ </pre>
115
+
116
+ The enum field works like any other model attribute. It can be mass-assigned using @update_attribute(s)@.
117
+
118
+ h2. Special Cases
119
+
120
+ What if your enum class name is not the same as your model's attribute name? No problem! Just use a second arugment in @classy_enum_attr@ to declare the attribute name. In this case, the model's attribute is called *alarm_priority*.
121
+
122
+ <pre>
123
+ class Alarm < ActiveRecord::Base
124
+ classy_enum_attr :priority, :alarm_priority
125
+ end
126
+
127
+ @alarm = Alarm.create(:alarm_priority => :medium)
128
+ @alarm.alarm_priority # => PriorityMedium
129
+ </pre>
130
+
131
+ h2. Model Validation
132
+
133
+ An ActiveRecord validator @validates_inclusion_of :field, :in => ENUM.all, :allow_nil => true@ is automatically added to your model when you use @classy_enum_attr@.
134
+
135
+ If your enum only has members low, mediume, and high, then the following validation behavior would be expected:
136
+
137
+ <pre>
138
+ @alarm = Alarm.new(:priority => :really_high)
139
+ @alarm.valid? # => false
140
+ @alarm.priority = :high
141
+ @alarm.valid? # => true
142
+ </pre>
143
+
144
+ h2. Working with ClassyEnum outside of ActiveRecord
145
+
146
+ While ClassyEnum was designed to be used directly with ActiveRecord, it can also be used outside of it. Here are some examples based on the enum class defined earlier in this document.
147
+
148
+ Instantiate an enum member subclass *PriorityLow*
149
+
150
+ <pre>
151
+ # These statements are all equivalent
152
+ low = Priority.build(:low)
153
+ low = Priority.build('low)
154
+ low = Priority.find(:low)
155
+ low = PriorityLow.new
156
+ </pre>
157
+
158
+ Get a list of the valid enum options
159
+
160
+ <pre>
161
+ Priority.valid_options # => low, mediume, high
94
162
  </pre>
95
163
 
96
164
  h2. Formtastic Support
@@ -103,10 +171,6 @@ Formtastic::SemanticFormHelper.builder = ClassyEnum::SemanticFormBuilder
103
171
 
104
172
  Then in your Formtastic view forms, use this syntax: @<%= f.input :priority, :as => :enum_select %>@
105
173
 
106
- h2. Notes
107
-
108
- An ActiveRecord validator @validates_inclusion_of :field, :in => ENUM.all, :allow_nil => true@ is automatically added to your model when you use @classy_enum_attr@.
109
-
110
174
  h2. Copyright
111
175
 
112
- Copyright (c) 2010 Peter Brown. See LICENSE for details.
176
+ Copyright (c) 2011 Peter Brown. See LICENSE for details.
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ begin
14
14
  gem.add_development_dependency 'rspec-rails', '~> 2.0'
15
15
  gem.add_development_dependency 'formtastic', '~> 1.1'
16
16
  gem.add_development_dependency 'sqlite3-ruby'
17
- gem.add_dependency "activerecord", ">= 2.3"
17
+ gem.add_development_dependency "activerecord", ">= 2.3"
18
18
  end
19
19
  Jeweler::GemcutterTasks.new
20
20
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.7.0
data/classy_enum.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{classy_enum}
8
- s.version = "0.6.1"
8
+ s.version = "0.7.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Peter Brown"]
12
- s.date = %q{2010-12-12}
12
+ s.date = %q{2011-01-29}
13
13
  s.description = %q{A utility that adds class based enum functionality to ActiveRecord attributes}
14
14
  s.email = %q{github@lette.us}
15
15
  s.extra_rdoc_files = [
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
42
42
  s.homepage = %q{http://github.com/beerlington/classy_enum}
43
43
  s.rdoc_options = ["--charset=UTF-8"]
44
44
  s.require_paths = ["lib"]
45
- s.rubygems_version = %q{1.3.7}
45
+ s.rubygems_version = %q{1.4.2}
46
46
  s.summary = %q{A class based enumerator utility for Ruby on Rails}
47
47
  s.test_files = [
48
48
  "spec/classy_enum_attributes_spec.rb",
@@ -52,7 +52,6 @@ Gem::Specification.new do |s|
52
52
  ]
53
53
 
54
54
  if s.respond_to? :specification_version then
55
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
55
  s.specification_version = 3
57
56
 
58
57
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -60,7 +59,7 @@ Gem::Specification.new do |s|
60
59
  s.add_development_dependency(%q<rspec-rails>, ["~> 2.0"])
61
60
  s.add_development_dependency(%q<formtastic>, ["~> 1.1"])
62
61
  s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
63
- s.add_runtime_dependency(%q<activerecord>, [">= 2.3"])
62
+ s.add_development_dependency(%q<activerecord>, [">= 2.3"])
64
63
  else
65
64
  s.add_dependency(%q<rspec>, ["~> 2.0"])
66
65
  s.add_dependency(%q<rspec-rails>, ["~> 2.0"])
@@ -1,7 +1,7 @@
1
1
  class ClassyEnumGenerator < Rails::Generator::NamedBase
2
2
 
3
3
  def manifest
4
- record do |m|
4
+ record do |m|
5
5
  m.directory 'app/enums'
6
6
  m.template "enum.rb", "app/enums/#{file_name}.rb"
7
7
  end
@@ -2,6 +2,6 @@ class <%= class_name %> < ClassyEnum::Base
2
2
  enum_classes <%= args.map {|a| ":#{a}"}.join(", ") %>
3
3
  end
4
4
  <% args.each do |arg| %>
5
- class <%= class_name + arg.camelize %>
5
+ class <%= class_name + arg.camelize %> < <%= class_name %>
6
6
  end
7
- <% end %>
7
+ <% end %>
data/lib/classy_enum.rb CHANGED
@@ -1,13 +1,30 @@
1
1
  require "classy_enum/attributes"
2
2
 
3
3
  if Gem.available? 'formtastic'
4
- require 'formtastic'
4
+ require 'formtastic'
5
5
  require 'classy_enum/semantic_form_builder'
6
6
  end
7
7
 
8
8
  module ClassyEnum
9
9
 
10
10
  class Base
11
+
12
+ # Macro for defining enum members within a ClassyEnum class.
13
+ # Accepts an array of symbols or strings which are converted to
14
+ # ClassyEnum members as descents of their parent class.
15
+ #
16
+ # ==== Example
17
+ # # Define an enum called Priority with three child classes
18
+ # class Priority < ClassyEnum::Base
19
+ # enum_classes :low, :medium, :high
20
+ # end
21
+ #
22
+ # The child classes will be defined with the following constants:
23
+ # PriorityLow, PriorityMedium, and PriorityHigh
24
+ #
25
+ # These child classes can be instantiated with either:
26
+ # Priority.build(:low) or PriorityLow.new
27
+ #
11
28
  def self.enum_classes(*options)
12
29
  self.send(:attr_reader, :enum_classes)
13
30
 
@@ -18,6 +35,8 @@ module ClassyEnum
18
35
  options.each_with_index do |option, index|
19
36
 
20
37
  klass = Class.new(self) do
38
+ include InstanceMethods
39
+
21
40
  attr_reader :to_s, :to_sym, :index
22
41
 
23
42
  @index = index + 1
@@ -29,13 +48,6 @@ module ClassyEnum
29
48
  @index = self.class.instance_variable_get('@index')
30
49
  end
31
50
 
32
- def name
33
- @to_s.titleize
34
- end
35
-
36
- def <=> other
37
- @index <=> other.index
38
- end
39
51
  end
40
52
 
41
53
  klass_name = "#{self}#{option.to_s.camelize}"
@@ -45,29 +57,123 @@ module ClassyEnum
45
57
  end
46
58
 
47
59
  module ClassMethods
48
-
60
+
61
+ # Build a new ClassyEnum child instance
62
+ #
63
+ # ==== Example
64
+ # # Create an Enum with some elements
65
+ # class Priority < ClassyEnum::Base
66
+ # enum_classes :low, :medium, :high
67
+ # end
68
+ #
69
+ # Priority.build(:low) # => PriorityLow.new
49
70
  def build(option)
50
71
  return option if option.blank?
51
72
  return TypeError.new("Valid #{self} options are #{self.valid_options}") unless self::OPTIONS.include? option.to_sym
52
73
  Object.const_get("#{self}#{option.to_s.camelize}").new
53
74
  end
54
-
55
- # Alias of build
56
- def find(option); build(option); end;
57
75
 
76
+ alias :find :build
77
+
78
+ # Returns an array of all instantiated enums
79
+ #
80
+ # ==== Example
81
+ # # Create an Enum with some elements
82
+ # class Priority < ClassyEnum::Base
83
+ # enum_classes :low, :medium, :high
84
+ # end
85
+ #
86
+ # Priority.all # => [PriorityLow.new, PriorityMedium.new, PriorityHigh.new]
58
87
  def all
59
88
  self::OPTIONS.map {|e| build(e) }
60
89
  end
61
-
62
- # Uses the name field for select options
90
+
91
+ # Returns a 2D array for Rails select helper options.
92
+ # Also used internally for Formtastic support
93
+ #
94
+ # ==== Example
95
+ # # Create an Enum with some elements
96
+ # class Priority < ClassyEnum::Base
97
+ # enum_classes :low, :really_high
98
+ # end
99
+ #
100
+ # Priority.select_options # => [["Low", "low"], ["Really High", "really_high"]]
63
101
  def select_options
64
102
  all.map {|e| [e.name, e.to_s] }
65
103
  end
66
-
104
+
105
+ # Returns a comma separated list of valid enum options.
106
+ # Also used internally for ActiveRecord model validation error messages
107
+ #
108
+ # ==== Example
109
+ # # Create an Enum with some elements
110
+ # class Priority < ClassyEnum::Base
111
+ # enum_classes :low, :medium, :high
112
+ # end
113
+ #
114
+ # Priority.valid_options # => "low, medium, high"
67
115
  def valid_options
68
116
  self::OPTIONS.map(&:to_s).join(', ')
69
117
  end
70
-
118
+
119
+ end
120
+
121
+ module InstanceMethods
122
+ # Returns string representing enum in Rails titleize format
123
+ #
124
+ # ==== Example
125
+ # # Create an Enum with some elements
126
+ # class Priority < ClassyEnum::Base
127
+ # enum_classes :low, :medium, :high, :really_high
128
+ # end
129
+ #
130
+ # @priority = Priority.build(:really_high)
131
+ # @priority.name # => "Really High"
132
+ def name
133
+ @to_s.titleize
134
+ end
135
+
136
+ # Sort an array of elements based on the order they are defined
137
+ #
138
+ # ==== Example
139
+ # # Create an Enum with some elements
140
+ # class Priority < ClassyEnum::Base
141
+ # enum_classes :low, :medium, :high
142
+ # end
143
+ #
144
+ # @low = Priority.build(:low)
145
+ # @medium = Priority.build(:medium)
146
+ # @high = Priority.build(:high)
147
+ # priorities = [@low, @high, @medium]
148
+ # priorities.sort # => [@low, @medium, @high]
149
+ # priorities.max # => @high
150
+ # priorities.min # => @low
151
+ def <=> other
152
+ @index <=> other.index
153
+ end
154
+
155
+ # Determine if the enum attribute is a particular member.
156
+ # Accepts a symbol or string representing a member
157
+ #
158
+ # ==== Example
159
+ # # Create an Enum with some elements
160
+ # class Breed < ClassyEnum::Base
161
+ # enum_classes :golden_retriever, :snoop
162
+ # end
163
+ #
164
+ # # Create an ActiveRecord class using the Breed enum
165
+ # class Dog < ActiveRecord::Base
166
+ # classy_enum_attr :breed
167
+ # end
168
+ #
169
+ # @dog = Dog.new(:breed => :snoop)
170
+ # @dog.breed.is? :snoop # => true
171
+ # @dog.breed.is? 'snoop' # => true
172
+ # @dog.breed.is? :golden_retriever # => false
173
+ def is?(obj)
174
+ obj.to_s == to_s
175
+ end
176
+
71
177
  end
72
178
 
73
179
  end
@@ -1,6 +1,23 @@
1
1
  module ClassyEnum
2
2
  module Attributes
3
3
 
4
+ # Class macro used to associate an enum with an attribute on an ActiveRecord model.
5
+ # This method is automatically added to all ActiveRecord models when the classy_enum gem
6
+ # is installed. Accepts an argument for the enum class to be associated with
7
+ # the model. If the enum class name is different than the field name, then an optional
8
+ # field name can be passed. ActiveRecord validation is automatically added to ensure
9
+ # that a value is one of its pre-defined enum members.
10
+ #
11
+ # ==== Example
12
+ # # Associate an enum Priority with Alarm model's priority attribute
13
+ # class Alarm < ActiveRecord::Base
14
+ # classy_enum_attr :priority
15
+ # end
16
+ #
17
+ # # Associate an enum Priority with Alarm model's alarm_priority attribute
18
+ # class Alarm < ActiveRecord::Base
19
+ # classy_enum_attr :priority, :alarm_priority
20
+ # end
4
21
  def classy_enum_attr(klass, method=nil)
5
22
 
6
23
  method ||= klass
@@ -14,12 +31,12 @@ module ClassyEnum
14
31
  record.errors.add(attr_name, "must be one of #{klass.all.map(&:to_sym).join(', ')}") unless klass.all.map(&:to_s).include? value.to_s
15
32
  end
16
33
 
17
- # Define getter method
34
+ # Define getter method that returns a ClassyEnum instance
18
35
  define_method method do
19
36
  klass.build(super())
20
37
  end
21
38
 
22
- # Define setter method
39
+ # Define setter method that accepts either string or symbol for member
23
40
  define_method "#{method}=" do |value|
24
41
  super(value.to_s)
25
42
  end
@@ -1,5 +1,5 @@
1
1
  module ClassyEnum
2
- class SemanticFormBuilder < Formtastic::SemanticFormBuilder
2
+ class SemanticFormBuilder < Formtastic::SemanticFormBuilder # :nodoc: all
3
3
  def enum_select_input(method, options)
4
4
  enum_class = object.send(method)
5
5
 
@@ -11,14 +11,14 @@ module ClassyEnum
11
11
  options[:collection] = enum_class.class.superclass.select_options
12
12
  options[:selected] = enum_class.to_s
13
13
  end
14
-
14
+
15
15
  options[:include_blank] = false
16
-
16
+
17
17
  select_input(method, options)
18
18
  end
19
19
  end
20
-
21
- module Error
20
+
21
+ module Error # :nodoc: all
22
22
  def self.invalid_classy_enum_object(method)
23
23
  raise "#{method} is not a ClassyEnum object"
24
24
  end
@@ -6,7 +6,7 @@ class ClassyEnumGenerator < Rails::Generators::NamedBase
6
6
 
7
7
  source_root File.expand_path("../templates", __FILE__)
8
8
 
9
- def copy_files
9
+ def copy_files # :nodoc:
10
10
  empty_directory 'app/enums'
11
11
  template "enum.rb", "app/enums/#{file_name}.rb"
12
12
  end
@@ -2,6 +2,6 @@ class <%= class_name %> < ClassyEnum::Base
2
2
  enum_classes <%= values.map {|a| ":#{a}"}.join(", ") %>
3
3
  end
4
4
  <% values.each do |arg| %>
5
- class <%= class_name + arg.camelize %>
5
+ class <%= class_name + arg.camelize %> < <%= class_name %>
6
6
  end
7
- <% end %>
7
+ <% end %>
@@ -14,9 +14,9 @@ describe "A Dog Collection" do
14
14
  end
15
15
 
16
16
  describe "A Dog" do
17
-
17
+
18
18
  before(:each) { @dog = Dog.new(:breed => :golden_retriever) }
19
-
19
+
20
20
  it "should have an enumerable breed" do
21
21
  @dog.breed.class.should == BreedGoldenRetriever
22
22
  end
@@ -25,13 +25,17 @@ describe "A Dog" do
25
25
  @dog.breed.should respond_to('enum_classes')
26
26
  end
27
27
 
28
+ it "should know which member the enum is" do
29
+ @dog.breed.is?(:golden_retriever).should be_true
30
+ end
31
+
28
32
  it "should be valid with a valid option" do
29
33
  @dog.should be_valid
30
34
  end
31
35
 
32
36
  context "with an invalid breed option" do
33
37
  before { @dog.breed = :golden_doodle }
34
-
38
+
35
39
  it "should not be valid with an invalid option" do
36
40
  @dog.should_not be_valid
37
41
  end
@@ -40,17 +44,17 @@ describe "A Dog" do
40
44
  @dog.valid?
41
45
  @dog.errors.should include(:breed)
42
46
  end
43
-
47
+
44
48
  it "should have an error message containing the right options" do
45
49
  @dog.valid?
46
50
  @dog.errors[:breed].should include("must be one of #{Breed.all.map(&:to_sym).join(', ')}")
47
51
  end
48
52
  end
49
-
53
+
50
54
  end
51
55
 
52
56
  class Thing < ActiveRecord::Base
53
- classy_enum_attr :breed, :dog_breed
57
+ classy_enum_attr :breed, :dog_breed
54
58
  end
55
59
 
56
60
  describe "A Thing" do
@@ -1,8 +1,8 @@
1
1
  require "spec/spec_helper"
2
2
 
3
- describe 'using enum_select input' do
3
+ describe 'using enum_select input' do
4
4
  include FormtasticSpecHelper
5
-
5
+
6
6
  Formtastic::SemanticFormHelper.builder = ClassyEnum::SemanticFormBuilder
7
7
 
8
8
  # Copied from how formtastic tests its form helpers
@@ -12,9 +12,9 @@ describe 'using enum_select input' do
12
12
 
13
13
  context "when building a form with a classy_enum select" do
14
14
  before(:each) do
15
- @output = semantic_form_for(Dog.new(:breed => :snoop), :url => "/") do |builder|
16
- concat(builder.input(:breed, :as => :enum_select))
17
- end
15
+ @output = semantic_form_for(Dog.new(:breed => :snoop), :url => "/") do |builder|
16
+ concat(builder.input(:breed, :as => :enum_select))
17
+ end
18
18
  end
19
19
 
20
20
  it "should produce a form tag" do
@@ -34,9 +34,9 @@ describe 'using enum_select input' do
34
34
 
35
35
  context "when building a form with a classy_enum select, but the existing value is nil" do
36
36
  before(:each) do
37
- @output = semantic_form_for(Dog.new, :url => "/") do |builder|
38
- concat(builder.input(:other_breed, :as => :enum_select, :enum_class => :breed))
39
- end
37
+ @output = semantic_form_for(Dog.new, :url => "/") do |builder|
38
+ concat(builder.input(:other_breed, :as => :enum_select, :enum_class => :breed))
39
+ end
40
40
  end
41
41
 
42
42
  it "should produce a form tag" do
@@ -56,9 +56,9 @@ describe 'using enum_select input' do
56
56
 
57
57
  context "when building a form with a classy_enum select, using the enum_attr option" do
58
58
  before(:each) do
59
- @output = semantic_form_for(Dog.new, :url => "/") do |builder|
60
- concat(builder.input(:breed, :as => :enum_select))
61
- end
59
+ @output = semantic_form_for(Dog.new, :url => "/") do |builder|
60
+ concat(builder.input(:breed, :as => :enum_select))
61
+ end
62
62
  end
63
63
 
64
64
  it "should produce a form tag" do
@@ -78,19 +78,19 @@ describe 'using enum_select input' do
78
78
 
79
79
  it "should raise an error if the attribute is not a ClassyEnum object" do
80
80
  lambda do
81
- @output = semantic_form_for(Dog.new(:breed => :snoop), :url => "/") do |builder|
82
- concat(builder.input(:id, :as => :enum_select))
83
- end
81
+ @output = semantic_form_for(Dog.new(:breed => :snoop), :url => "/") do |builder|
82
+ concat(builder.input(:id, :as => :enum_select))
83
+ end
84
84
  end.should raise_error("id is not a ClassyEnum object")
85
85
  end
86
86
 
87
87
  it "should raise an error if the attribute is not a ClassyEnum object and its value is nil" do
88
88
  lambda do
89
- @output = semantic_form_for(Dog.new, :url => "/") do |builder|
90
- concat(builder.input(:id, :as => :enum_select))
91
- end
89
+ @output = semantic_form_for(Dog.new, :url => "/") do |builder|
90
+ concat(builder.input(:id, :as => :enum_select))
91
+ end
92
92
  end.should raise_error("id is not a ClassyEnum object")
93
93
  end
94
94
 
95
- end
95
+ end
96
96
 
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  class TestEnum < ClassyEnum::Base
4
4
  enum_classes :one, :two, :three
5
-
5
+
6
6
  def self.test_class_method?
7
7
  false
8
8
  end
@@ -22,63 +22,80 @@ class TestEnumTwo
22
22
  end
23
23
  end
24
24
 
25
- describe TestEnum do
25
+ describe "A ClassyEnum Descendent" do
26
26
 
27
27
  TestEnum::OPTIONS.each do |option|
28
28
  it "should define a TestEnum#{option.to_s.capitalize} class" do
29
29
  Object.const_defined?("TestEnum#{option.to_s.capitalize}").should be_true
30
30
  end
31
31
  end
32
-
32
+
33
33
  it "should return an array of enums" do
34
34
  TestEnum.all.map(&:class).should == [TestEnumOne, TestEnumTwo, TestEnumThree]
35
35
  end
36
-
36
+
37
37
  it "should return an array of enums for a select tag" do
38
38
  TestEnum.select_options.should == TestEnum::OPTIONS.map {|o| [TestEnum.build(o).name, TestEnum.build(o).to_s] }
39
39
  end
40
-
40
+
41
41
  it "should return a type error when adding an invalid option" do
42
42
  TestEnum.build(:invalid_option).class.should == TypeError
43
43
  end
44
-
45
- context "with a collection of enums" do
46
- before(:each) do
47
- @one = TestEnum.build(:one)
48
- @two = TestEnum.build(:two)
49
- @three = TestEnum.build(:three)
50
-
51
- @unordered = [@one, @three, @two]
52
- end
53
-
54
- it "should sort the enums" do
55
- @unordered.sort.should == [@one, @two, @three]
56
- end
57
-
58
- it "should find the max enum based on its order" do
59
- @unordered.max.should == @three
60
- end
61
- end
62
-
44
+
63
45
  it "should find an enum by symbol" do
64
46
  TestEnum.find(:one).class.should == TestEnumOne
65
47
  end
66
-
48
+
67
49
  it "should find an enum by string" do
68
50
  TestEnum.find("one").class.should == TestEnumOne
69
51
  end
70
52
 
53
+ it "should create an instance with a string" do
54
+ TestEnum.build("one").should be_a(TestEnumOne)
55
+ end
56
+ end
57
+
58
+ describe "A collection of ClassyEnums" do
59
+ before(:each) do
60
+ @one = TestEnum.build(:one)
61
+ @two = TestEnum.build(:two)
62
+ @three = TestEnum.build(:three)
63
+
64
+ @unordered = [@one, @three, @two]
65
+ end
66
+
67
+ it "should sort the enums" do
68
+ @unordered.sort.should == [@one, @two, @three]
69
+ end
70
+
71
+ it "should find the max enum based on its order" do
72
+ @unordered.max.should == @three
73
+ end
74
+ end
75
+
76
+ describe "A ClassyEnum element" do
77
+ it "should instantiate a member" do
78
+ TestEnumOne.new.should be_a(TestEnumOne)
79
+ end
80
+
81
+ it "should inherit the default class methods" do
82
+ TestEnumOne.test_class_method?.should be_false
83
+ end
71
84
  end
72
85
 
73
86
  describe "A ClassyEnum instance" do
74
87
  before { @enum = TestEnum.build(:one) }
75
-
88
+
76
89
  it "should build a TestEnum class" do
77
90
  @enum.class.should == TestEnumOne
78
91
  end
79
92
 
80
- it "should instantiate a member" do
81
- TestEnumOne.new.should be_a(TestEnumOne)
93
+ it "should return true for is_element?(:one)" do
94
+ @enum.is?(:one).should be_true
95
+ end
96
+
97
+ it "should return true for is_element?('one')" do
98
+ @enum.is?('one').should be_true
82
99
  end
83
100
 
84
101
  it "should be a TestEnum" do
@@ -88,7 +105,7 @@ describe "A ClassyEnum instance" do
88
105
  it "should convert to a string" do
89
106
  @enum.to_s.should == "one"
90
107
  end
91
-
108
+
92
109
  it "should convert to a symbol" do
93
110
  @enum.to_sym.should == :one
94
111
  end
@@ -96,25 +113,15 @@ describe "A ClassyEnum instance" do
96
113
  it "should have a name" do
97
114
  @enum.name.should == "One"
98
115
  end
99
-
116
+
100
117
  it "should inherit the default instance methods" do
101
118
  @enum.test_instance_method?.should be_false
102
119
  end
103
-
104
- it "should inherit the default class methods" do
105
- TestEnumOne.test_class_method?.should be_false
106
- end
107
-
108
- it "should create the same instance with a string or symbol" do
109
- @enum_string = TestEnum.build("one")
110
-
111
- @enum.class.should == @enum_string.class
112
- end
113
120
  end
114
121
 
115
122
  describe "An ClassyEnumValue" do
116
123
  before(:each) { @enum = TestEnum.build(:two) }
117
-
124
+
118
125
  it "should override the default instance methods" do
119
126
  @enum.test_instance_method?.should be_true
120
127
  end
data/spec/spec_helper.rb CHANGED
@@ -51,7 +51,7 @@ module FormtasticSpecHelper
51
51
 
52
52
  end
53
53
  end
54
-
54
+
55
55
  end
56
56
 
57
57
  module ActionView
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: classy_enum
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
5
- prerelease: false
4
+ hash: 3
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 6
9
- - 1
10
- version: 0.6.1
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Peter Brown
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-12 00:00:00 -05:00
18
+ date: 2011-01-29 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -90,7 +90,7 @@ dependencies:
90
90
  - 2
91
91
  - 3
92
92
  version: "2.3"
93
- type: :runtime
93
+ type: :development
94
94
  version_requirements: *id005
95
95
  description: A utility that adds class based enum functionality to ActiveRecord attributes
96
96
  email: github@lette.us
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  requirements: []
154
154
 
155
155
  rubyforge_project:
156
- rubygems_version: 1.3.7
156
+ rubygems_version: 1.4.2
157
157
  signing_key:
158
158
  specification_version: 3
159
159
  summary: A class based enumerator utility for Ruby on Rails