active_enum 0.3.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.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Adam Meehan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,134 @@
1
+ = ActiveEnum
2
+
3
+ Define enum classes in Rails and use them to enumerate ActiveRecord attributes. Brings together some ideas
4
+ of similar plugins that I liked and does it they way I prefer.
5
+
6
+ Enum values are stored in memory at the moment but I plan to add database and yaml.
7
+
8
+ == Install
9
+
10
+ On Gemcutter:
11
+
12
+ sudo gem install active_enum
13
+
14
+ And add to your Rails environment.rb
15
+
16
+ config.gem 'active_enum'
17
+
18
+ == Example
19
+
20
+ Define an enum class with values
21
+
22
+ class Sex < ActiveEnum::Base
23
+ value :id => 1, :name => 'Male'
24
+ value :id => 2, :name => 'Female'
25
+ end
26
+
27
+ Define using implicit id values
28
+
29
+ class Sex < ActiveEnum::Base
30
+ value :name => 'Male'
31
+ value :name => 'Female'
32
+ end
33
+
34
+ Beware that if you change the order of values defined in an enum which don't have explicit ids, then the ids will change.
35
+ This could corrupt your data if the enum values have been stored in a model record, as they will no longer map to
36
+ the original enum.
37
+
38
+ Enum class usage
39
+
40
+ Sex[1] # => 'Male'
41
+ Sex['Male'] # => 1
42
+ Sex[:male] # => 1
43
+ Sex.to_select # => [['Male', 1], ['Female',2]] for select form helpers
44
+
45
+ Use the enum to enumerate an ActiveRecord model attribute
46
+
47
+ class User < ActiveRecord::Base
48
+ enumerate :sex, :with => Sex
49
+ end
50
+
51
+ Skip the with option if the enum can be implied from the attribute
52
+
53
+ class User < ActiveRecord::Base
54
+ enumerate :sex
55
+ end
56
+
57
+ Define enum class implicitly in enumerate block
58
+
59
+ class User < ActiveRecord::Base
60
+ # defines UserSex enum
61
+ enumerate :sex do
62
+ value :name => 'Male'
63
+ end
64
+ end
65
+
66
+ Access the enum values and the enum class using the attribute method with a symbol for the enum component you want
67
+
68
+ user = User.new
69
+ user.sex = 1
70
+ user.sex # => 1
71
+
72
+ user.sex(:id) # => 1
73
+ user.sex(:name) # => 'Male'
74
+ user.sex(:enum) # => Sex
75
+
76
+ You can check if the attribute value matches a particular enum value by passing the enum value as an argument to the question method
77
+
78
+ user.sex?(:male) # => true
79
+ user.sex?(:Male) # => true
80
+ user.sex?('Male') # => true
81
+ user.sex?('Female') # => false
82
+
83
+ A convience method on the class is available to the enum class of any enumerated attribute
84
+
85
+ User.enum_for(:sex) # => Sex
86
+
87
+ You can set the default to return the enum name value for enumerated attribute
88
+
89
+ ActiveEnum.use_name_as_value = true
90
+ user.sex # => 'Male'
91
+
92
+ Define enum classes in bulk without class files, in an initializer file for example.
93
+
94
+ ActiveEnum.define do
95
+
96
+ # defines Sex
97
+ enum(:sex) do
98
+ value :name => 'Male'
99
+ value :name => 'Female'
100
+ end
101
+
102
+ # defines Language
103
+ enum(:language) do
104
+ value :name => 'English'
105
+ value :name => 'German'
106
+ end
107
+
108
+ end
109
+
110
+ All defined enum classes are stored in ActiveEnum.enum_classes array if you need look them up or iterate over them.
111
+
112
+ You can make an existing model class behave like an enum class with acts_as_enum
113
+
114
+ class User < ActiveRecord::Base
115
+ acts_as_enum :name_column => 'first_name'
116
+ end
117
+
118
+ Giving you the familiar enum methods
119
+
120
+ User[1]
121
+ User['Dave']
122
+ User.to_select
123
+
124
+
125
+ == TODO
126
+ * more docs
127
+ * storage options of memory, database or yaml
128
+ * use custom method name for the enumerated attribute
129
+ * named_scopes
130
+ * question methods for enum names e.g. user.male?
131
+ * possibly allow string enum values to assigned to attributes
132
+ * add enum value class for instances if there is a need
133
+
134
+ Copyright (c) 2009 Adam Meehan, released under the MIT license
@@ -0,0 +1,74 @@
1
+ require 'rubygems'
2
+ require 'rake/rdoctask'
3
+ require 'rake/gempackagetask'
4
+ require 'rubygems/specification'
5
+ require 'spec/rake/spectask'
6
+ require 'lib/active_enum/version'
7
+
8
+ GEM_NAME = "active_enum"
9
+ GEM_VERSION = ActiveEnum::VERSION
10
+ AUTHOR = "Adam Meehan"
11
+ EMAIL = "adam.meehan@gmail.com"
12
+ HOMEPAGE = "http://github.com/adzap/active_enum"
13
+ SUMMARY = "Define enum classes in Rails and use them to enumerate ActiveRecord attributes"
14
+
15
+ spec = Gem::Specification.new do |s|
16
+ s.name = GEM_NAME
17
+ s.version = GEM_VERSION
18
+ s.platform = Gem::Platform::RUBY
19
+ s.rubyforge_project = "active_enum"
20
+ s.has_rdoc = true
21
+ s.extra_rdoc_files = ["README.rdoc"]
22
+ s.summary = SUMMARY
23
+ s.description = s.summary
24
+ s.author = AUTHOR
25
+ s.email = EMAIL
26
+ s.homepage = HOMEPAGE
27
+
28
+ s.require_path = 'lib'
29
+ s.autorequire = GEM_NAME
30
+ s.files = %w(MIT-LICENSE README.rdoc Rakefile) + Dir.glob("{lib,spec}/**/*")
31
+ end
32
+
33
+ desc 'Default: run specs.'
34
+ task :default => :spec
35
+
36
+ spec_files = Rake::FileList["spec/**/*_spec.rb"]
37
+
38
+ desc "Run specs"
39
+ Spec::Rake::SpecTask.new do |t|
40
+ t.spec_files = spec_files
41
+ t.spec_opts = ["-c"]
42
+ end
43
+
44
+ desc "Generate code coverage"
45
+ Spec::Rake::SpecTask.new(:coverage) do |t|
46
+ t.spec_files = spec_files
47
+ t.rcov = true
48
+ t.rcov_opts = ['--exclude', 'spec,/var/lib/gems']
49
+ end
50
+
51
+ desc 'Generate documentation for plugin.'
52
+ Rake::RDocTask.new(:rdoc) do |rdoc|
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = 'ActiveEnum'
55
+ rdoc.options << '--line-numbers' << '--inline-source'
56
+ rdoc.rdoc_files.include('README')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
59
+
60
+ Rake::GemPackageTask.new(spec) do |pkg|
61
+ pkg.gem_spec = spec
62
+ end
63
+
64
+ desc "install the gem locally"
65
+ task :install => [:package] do
66
+ sh %{sudo gem install pkg/#{GEM_NAME}-#{GEM_VERSION}}
67
+ end
68
+
69
+ desc "create a gemspec file"
70
+ task :make_spec do
71
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
72
+ file.puts spec.to_ruby
73
+ end
74
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_enum/base'
2
+ require 'active_enum/extensions'
3
+ require 'active_enum/acts_as_enum'
4
+ require 'active_enum/version'
5
+
6
+ module ActiveEnum
7
+ mattr_accessor :enum_classes
8
+ self.enum_classes = []
9
+
10
+ mattr_accessor :use_name_as_value
11
+ self.use_name_as_value = false
12
+
13
+ class Configuration
14
+ def enum(name, &block)
15
+ class_name = name.to_s.classify
16
+ class_def = <<-end_eval
17
+ class #{class_name} < ActiveEnum::Base
18
+ end
19
+ end_eval
20
+ eval(class_def, TOPLEVEL_BINDING)
21
+ new_enum = Module.const_get(class_name)
22
+ new_enum.class_eval(&block)
23
+ end
24
+ end
25
+
26
+ def self.define(&block)
27
+ raise "Define requires block" unless block_given?
28
+ Configuration.new.instance_eval(&block)
29
+ end
30
+
31
+ end
@@ -0,0 +1,57 @@
1
+ module ActiveEnum
2
+
3
+ module ActsAsEnum
4
+
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def acts_as_enum(options={})
12
+ class_inheritable_accessor :active_enum_options
13
+ self.active_enum_options = options.reverse_merge(:name_column => 'name')
14
+ named_scope :enum_values,
15
+ :select => "#{primary_key}, #{active_enum_options[:name_column]}",
16
+ :conditions => active_enum_options[:conditions],
17
+ :order => active_enum_options[:order]
18
+ end
19
+
20
+ def ids
21
+ enum_values.map {|v| v.id }
22
+ end
23
+
24
+ def names
25
+ enum_values.map {|v| v.send(active_enum_options[:name_column]) }
26
+ end
27
+
28
+ def to_select
29
+ enum_values.map {|v| [v.send(active_enum_options[:name_column]), v.id] }
30
+ end
31
+
32
+ def [](index)
33
+ if index.is_a?(Fixnum)
34
+ v = lookup_by_id(index)
35
+ v.send(active_enum_options[:name_column]) unless v.blank?
36
+ else
37
+ v = lookup_by_name(index)
38
+ v.id unless v.blank?
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def lookup_by_id(index)
45
+ enum_values.find_by_id(index)
46
+ end
47
+
48
+ def lookup_by_name(index)
49
+ enum_values.find(:first, :conditions => ["#{active_enum_options[:name_column]} like ?", index.to_s])
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
56
+
57
+ ActiveRecord::Base.send :include, ActiveEnum::ActsAsEnum
@@ -0,0 +1,76 @@
1
+ module ActiveEnum
2
+ class DuplicateValue < StandardError; end
3
+
4
+ class Base
5
+
6
+ class << self
7
+
8
+ def inherited(subclass)
9
+ ActiveEnum.enum_classes << subclass
10
+ end
11
+
12
+ # :id => 1, :title => 'Foo'
13
+ # :title => 'Foo'
14
+ #
15
+ def value(enum_value={})
16
+ @values ||= []
17
+
18
+ id = enum_value[:id] || next_id
19
+ check_duplicate(id, enum_value[:name])
20
+
21
+ @values << [id, enum_value[:name]]
22
+ @values.sort! {|a,b| a[0] <=> b[0] }
23
+ end
24
+
25
+ def all
26
+ @values || []
27
+ end
28
+
29
+ def ids
30
+ @values.map {|v| v[0] }
31
+ end
32
+
33
+ def names
34
+ @values.map {|v| v[1] }
35
+ end
36
+
37
+ def to_select
38
+ @values.map {|v| [v[1], v[0]] }
39
+ end
40
+
41
+ def [](index)
42
+ if index.is_a?(Fixnum)
43
+ row = lookup_by_id(index)
44
+ row[1] if row
45
+ else
46
+ row = lookup_by_name(index)
47
+ row[0] if row
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def lookup_by_id(index)
54
+ @values.assoc(index)
55
+ end
56
+
57
+ def lookup_by_name(index)
58
+ @values.rassoc(index.to_s) || @values.rassoc(index.to_s.titleize)
59
+ end
60
+
61
+ def next_id
62
+ (ids.max || 0) + 1
63
+ end
64
+
65
+ def check_duplicate(id, name)
66
+ if lookup_by_id(id)
67
+ raise ActiveEnum::DuplicateValue, "The id #{id} is already defined for #{self} enum."
68
+ elsif lookup_by_name(name)
69
+ raise ActiveEnum::DuplicateValue, "The name #{name} is already defined for #{self} enum."
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,130 @@
1
+ module ActiveEnum
2
+ class EnumNotFound < StandardError; end
3
+
4
+ module Extensions
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ base.class_inheritable_accessor :enumerated_attributes
9
+ base.enumerated_attributes = {}
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Declare an attribute to be enumerated by an enum class
15
+ #
16
+ # class Person < ActiveRecord::Base
17
+ # enumerate :sex, :with => Sex
18
+ # enumerate :sex # implies a Sex enum class exists
19
+ #
20
+ # # Pass a block to create implicit enum class as ModelAttribute e.g. PersonSex
21
+ # enumerate :sex do
22
+ # value :id => 1, :name => 'Male'
23
+ # end
24
+ #
25
+ def enumerate(attribute, options={}, &block)
26
+ attribute = attribute.to_sym
27
+ if block_given?
28
+ enum_name = "#{self.to_s.underscore}_#{attribute}"
29
+ ActiveEnum.define { enum(enum_name, &block) }
30
+ enum = enum_name.classify.constantize
31
+ else
32
+ enum = options[:with] || attribute.to_s.classify.constantize
33
+ end
34
+
35
+ self.enumerated_attributes[attribute] = enum
36
+
37
+ define_active_enum_read_method(attribute)
38
+ define_active_enum_write_method(attribute)
39
+ define_active_enum_question_method(attribute)
40
+ rescue NameError => e
41
+ raise e unless e.message =~ /uninitialized constant/
42
+ raise ActiveEnum::EnumNotFound, "Enum class could not be found for attribute '#{attribute}' in class #{self}. Specify the enum class using the :with option."
43
+ end
44
+
45
+ def enum_for(attribute)
46
+ self.enumerated_attributes[attribute.to_sym]
47
+ end
48
+
49
+ # Define read method to allow an argument for the enum component
50
+ #
51
+ # user.sex
52
+ # user.sex(:id)
53
+ # user.sex(:name)
54
+ # user.sex(:enum)
55
+ #
56
+ def define_active_enum_read_method(attribute)
57
+ unless instance_method_already_implemented?(attribute)
58
+ define_read_method(attribute, attribute.to_s, columns_hash[attribute.to_s])
59
+ end
60
+
61
+ old_method = "#{attribute}_without_enum"
62
+ define_method("#{attribute}_with_enum") do |*arg|
63
+ arg = arg.first
64
+ value = send(old_method)
65
+
66
+ enum = self.class.enum_for(attribute)
67
+ case arg
68
+ when :id
69
+ value if enum[value]
70
+ when :name
71
+ enum[value]
72
+ when :enum
73
+ enum
74
+ else
75
+ ActiveEnum.use_name_as_value ? enum[value] : value
76
+ end
77
+ end
78
+
79
+ alias_method_chain attribute, :enum
80
+ end
81
+
82
+ # Define write method to also handle enum value
83
+ #
84
+ # user.sex = 1
85
+ # user.sex = :male
86
+ #
87
+ def define_active_enum_write_method(attribute)
88
+ unless instance_method_already_implemented?("#{attribute}=")
89
+ define_write_method(attribute)
90
+ end
91
+
92
+ old_method = "#{attribute}_without_enum="
93
+ define_method("#{attribute}_with_enum=") do |arg|
94
+ enum = self.class.enum_for(attribute)
95
+ if arg.is_a?(Symbol)
96
+ value = enum[arg]
97
+ send(old_method, value)
98
+ else
99
+ send(old_method, arg)
100
+ end
101
+ end
102
+
103
+ alias_method_chain "#{attribute}=".to_sym, :enum
104
+ end
105
+
106
+ # Define question method to check enum value against attribute value
107
+ #
108
+ # user.sex?(:male)
109
+ #
110
+ def define_active_enum_question_method(attribute)
111
+ define_question_method(attribute) unless instance_method_already_implemented?("#{attribute}?")
112
+
113
+ old_method = "#{attribute}_without_enum?"
114
+ define_method("#{attribute}_with_enum?") do |*arg|
115
+ arg = arg.first
116
+ if arg
117
+ send(attribute) == self.class.enum_for(attribute)[arg]
118
+ else
119
+ send(old_method)
120
+ end
121
+ end
122
+ alias_method_chain "#{attribute}?".to_sym, :enum
123
+ end
124
+
125
+ end
126
+
127
+ end
128
+ end
129
+
130
+ ActiveRecord::Base.send :include, ActiveEnum::Extensions
@@ -0,0 +1,3 @@
1
+ module ActiveEnum
2
+ VERSION = '0.3.0'
3
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class Person < ActiveRecord::Base
4
+ acts_as_enum :name_column => 'first_name'
5
+ end
6
+
7
+ describe ActiveEnum::ActsAsEnum do
8
+ before(:all) do
9
+ @person = Person.create!(:first_name => 'Dave', :last_name => 'Smith')
10
+ end
11
+
12
+ it 'return name column value when passing id to [] method' do
13
+ Person[@person.id].should == @person.first_name
14
+ end
15
+
16
+ it 'return id column value when passing string name to [] method' do
17
+ Person['Dave'].should == @person.id
18
+ Person['dave'].should == @person.id
19
+ end
20
+
21
+ it 'return id column value when passing symbol name to [] method' do
22
+ Person[:dave].should == @person.id
23
+ end
24
+
25
+ it 'should return array for select helpers from to_select' do
26
+ Person.to_select.should == [[@person.first_name, @person.id]]
27
+ end
28
+ end
@@ -0,0 +1,120 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe ActiveEnum::Base do
4
+ it 'should return empty array from :all method when no values defined' do
5
+ ActiveEnum.enum_classes = []
6
+ class NewEnum < ActiveEnum::Base
7
+ end
8
+ ActiveEnum.enum_classes.should == [NewEnum]
9
+ end
10
+
11
+ it 'should return empty array from :all method when no values defined' do
12
+ define_enum.all.should == []
13
+ end
14
+
15
+ it 'should allow me to define a value with an id and name' do
16
+ enum = define_enum do
17
+ value :id => 1, :name => 'Name'
18
+ end
19
+ enum.all.should == [[1,'Name']]
20
+ end
21
+
22
+ it 'should allow me to define a value with a name only' do
23
+ enum = define_enum do
24
+ value :name => 'Name'
25
+ end
26
+ enum.all.should == [[1,'Name']]
27
+ end
28
+
29
+ it 'should increment value ids when defined without ids' do
30
+ enum = define_enum do
31
+ value :name => 'Name 1'
32
+ value :name => 'Name 2'
33
+ end
34
+ enum.all.should == [[1,'Name 1'], [2, 'Name 2']]
35
+ end
36
+
37
+ it 'should raise error is the id is a duplicate' do
38
+ lambda do
39
+ define_enum do
40
+ value :id => 1, :name => 'Name 1'
41
+ value :id => 1, :name => 'Name 2'
42
+ end
43
+ end.should raise_error(ActiveEnum::DuplicateValue)
44
+ end
45
+
46
+ it 'should raise error is the name is a duplicate' do
47
+ lambda do
48
+ define_enum do
49
+ value :id => 1, :name => 'Name'
50
+ value :id => 2, :name => 'Name'
51
+ end
52
+ end.should raise_error(ActiveEnum::DuplicateValue)
53
+ end
54
+
55
+ it 'should return sorted values by id from :all' do
56
+ enum = define_enum do
57
+ value :id => 2, :name => 'Name 2'
58
+ value :id => 1, :name => 'Name 1'
59
+ end
60
+ enum.all.first[0].should == 1
61
+ end
62
+
63
+ it 'should return array of ids' do
64
+ enum = define_enum do
65
+ value :id => 1, :name => 'Name 1'
66
+ value :id => 2, :name => 'Name 2'
67
+ end
68
+ enum.ids.should == [1,2]
69
+ end
70
+
71
+ it 'should return array of names' do
72
+ enum = define_enum do
73
+ value :id => 1, :name => 'Name 1'
74
+ value :id => 2, :name => 'Name 2'
75
+ end
76
+ enum.names.should == ['Name 1', 'Name 2']
77
+ end
78
+
79
+ describe "element reference method" do
80
+
81
+ it 'should return name when given an id' do
82
+ enum = define_enum do
83
+ value :id => 1, :name => 'Name 1'
84
+ value :id => 2, :name => 'Name 2'
85
+ end
86
+ enum[1].should == 'Name 1'
87
+ end
88
+
89
+ it 'should return id when given a name' do
90
+ enum = define_enum do
91
+ value :id => 1, :name => 'Name 1'
92
+ value :id => 2, :name => 'Name 2'
93
+ end
94
+ enum['Name 1'].should == 1
95
+ end
96
+
97
+ it 'should return id when given a symbol of the name' do
98
+ enum = define_enum do
99
+ value :id => 1, :name => 'Name 1'
100
+ value :id => 2, :name => 'Name 2'
101
+ end
102
+ enum[:Name_1].should == 1
103
+ enum[:name_1].should == 1
104
+ end
105
+
106
+ end
107
+
108
+ it 'should return array for select helpers from to_select' do
109
+ enum = define_enum do
110
+ value :id => 1, :name => 'Name 1'
111
+ value :id => 2, :name => 'Name 2'
112
+ end
113
+ enum.to_select.should == [['Name 1',1], ['Name 2',2]]
114
+ end
115
+
116
+ def define_enum(&block)
117
+ Class.new(ActiveEnum::Base, &block)
118
+ end
119
+
120
+ end
@@ -0,0 +1,163 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class Sex < ActiveEnum::Base
4
+ value :id => 1, :name => 'Male'
5
+ value :id => 2, :name => 'Female'
6
+ end
7
+
8
+ describe ActiveEnum::Extensions do
9
+ before do
10
+ Person.class_eval do
11
+ enumerate :sex, :with => Sex
12
+ end
13
+ @person = Person.new(:sex =>1)
14
+ end
15
+
16
+ it 'should add class :enumerate method to ActiveRecord' do
17
+ ActiveRecord::Base.should respond_to(:enumerate)
18
+ end
19
+
20
+ it 'should add class :enum_for method to ActiveRecord' do
21
+ ActiveRecord::Base.should respond_to(:enum_for)
22
+ end
23
+
24
+ it 'should allow implicit enumeration class from attribute name' do
25
+ Person.class_eval do
26
+ enumerate :sex
27
+ end
28
+ Person.enum_for(:sex).should == Sex
29
+ end
30
+
31
+ it 'should allow implicit enumeration class from block' do
32
+ Person.class_eval do
33
+ enumerate :sex do
34
+ value :id => 1, :name => 'Male'
35
+ end
36
+ end
37
+ Person.enum_for(:sex).should == PersonSex
38
+ end
39
+
40
+ it 'should raise error if implicit enumeration class cannot be found' do
41
+ lambda do
42
+ Person.class_eval { enumerate :first_name }
43
+ end.should raise_error(ActiveEnum::EnumNotFound)
44
+ end
45
+
46
+ describe "attribute with value" do
47
+ it 'should return value with no arg' do
48
+ @person.sex.should == 1
49
+ end
50
+
51
+ it 'should return enum id for value' do
52
+ @person.sex(:id).should == 1
53
+ end
54
+
55
+ it 'should return enum name for value' do
56
+ @person.sex(:name).should == 'Male'
57
+ end
58
+
59
+ it 'should return enum class for attribute' do
60
+ @person.sex(:enum).should == Sex
61
+ end
62
+ end
63
+
64
+ describe "nil attribute value" do
65
+ before do
66
+ @person.sex = nil
67
+ end
68
+
69
+ it 'should return nil with no arg' do
70
+ @person.sex.should be_nil
71
+ end
72
+
73
+ it 'should return nil enum id' do
74
+ @person.sex(:id).should be_nil
75
+ end
76
+
77
+ it 'should return nil enum name' do
78
+ @person.sex(:name).should be_nil
79
+ end
80
+
81
+ it 'should return enum class for attribute' do
82
+ @person.sex(:enum).should == Sex
83
+ end
84
+ end
85
+
86
+ describe "attribute with undefined value" do
87
+ before do
88
+ @person.sex = -1
89
+ end
90
+
91
+ it 'should return value with no arg' do
92
+ @person.sex.should == -1
93
+ end
94
+
95
+ it 'should return nil enum id' do
96
+ @person.sex(:id).should be_nil
97
+ end
98
+
99
+ it 'should return nil enum name' do
100
+ @person.sex(:name).should be_nil
101
+ end
102
+
103
+ it 'should return enum class for attribute' do
104
+ @person.sex(:enum).should == Sex
105
+ end
106
+ end
107
+
108
+ describe "attribute question method" do
109
+ before do
110
+ @person.sex = 1
111
+ end
112
+
113
+ it 'should return normal value without arg' do
114
+ @person.sex?.should be_true
115
+ @person.sex = nil
116
+ @person.sex?.should be_false
117
+ end
118
+
119
+ it 'should return true if string name matches for id value' do
120
+ @person.sex?("Male").should be_true
121
+ end
122
+
123
+ it 'should return true if symbol name matches for id value' do
124
+ @person.sex?(:male).should be_true
125
+ @person.sex?(:Male).should be_true
126
+ end
127
+
128
+ it 'should return false if name does not match for id value' do
129
+ @person.sex?("Female").should be_false
130
+ @person.sex?(:female).should be_false
131
+ @person.sex?(:Female).should be_false
132
+ end
133
+ end
134
+
135
+ describe "assigning enum name symbol to attribute" do
136
+
137
+ it 'should store id value when valid enum name' do
138
+ @person.sex = :female
139
+ @person.sex.should == 2
140
+ end
141
+
142
+ it 'should store nil value when invalid enum name' do
143
+ @person.sex = :invalid
144
+ @person.sex.should == nil
145
+ end
146
+
147
+ end
148
+
149
+ describe "use enum name as attribute value" do
150
+ before(:all) do
151
+ ActiveEnum.use_name_as_value = true
152
+ end
153
+
154
+ it 'should return text name value for attribute' do
155
+ @person.sex.should == 'Male'
156
+ end
157
+
158
+ after(:all) do
159
+ ActiveEnum.use_name_as_value = false
160
+ end
161
+ end
162
+
163
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Bulk enum definitions" do
4
+
5
+ it 'define enum constants using block' do
6
+ ActiveEnum.define do
7
+ enum(:foo) do
8
+ value :id => 1, :name => 'Foo 1'
9
+ end
10
+
11
+ enum(:bar) do
12
+ value :id => 1, :name => 'Bar 1'
13
+ end
14
+ end
15
+
16
+ Foo.all.should == [[1,'Foo 1']]
17
+ Bar.all.should == [[1,'Bar 1']]
18
+ end
19
+
20
+ end
@@ -0,0 +1,13 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ create_table :people, :force => true do |t|
4
+ t.string :first_name
5
+ t.string :last_name
6
+ t.integer :sex
7
+ end
8
+
9
+ create_table :sexes, :force => true do |t|
10
+ t.string :name
11
+ end
12
+
13
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'spec'))
3
+
4
+ require 'rubygems'
5
+ require 'spec/autorun'
6
+
7
+ require 'active_record'
8
+ require 'active_enum'
9
+
10
+ RAILS_ROOT = File.dirname(__FILE__)
11
+
12
+ ActiveRecord::Migration.verbose = false
13
+ ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
14
+
15
+ require 'schema'
16
+
17
+ class Person < ActiveRecord::Base; end
18
+
19
+ module SpecHelper
20
+
21
+ end
22
+
23
+ Spec::Runner.configure do |config|
24
+ config.include SpecHelper
25
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_enum
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Meehan
8
+ autorequire: active_enum
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-05 00:00:00 +11:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Define enum classes in Rails and use them to enumerate ActiveRecord attributes
17
+ email: adam.meehan@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - MIT-LICENSE
26
+ - README.rdoc
27
+ - Rakefile
28
+ - lib/active_enum.rb
29
+ - lib/active_enum/base.rb
30
+ - lib/active_enum/version.rb
31
+ - lib/active_enum/extensions.rb
32
+ - lib/active_enum/acts_as_enum.rb
33
+ - spec/schema.rb
34
+ - spec/active_enum_spec.rb
35
+ - spec/spec_helper.rb
36
+ - spec/active_enum/acts_as_enum_spec.rb
37
+ - spec/active_enum/extensions_spec.rb
38
+ - spec/active_enum/base_spec.rb
39
+ has_rdoc: true
40
+ homepage: http://github.com/adzap/active_enum
41
+ licenses: []
42
+
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ requirements: []
61
+
62
+ rubyforge_project: active_enum
63
+ rubygems_version: 1.3.4
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Define enum classes in Rails and use them to enumerate ActiveRecord attributes
67
+ test_files: []
68
+