active_enum 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+