From 567d2e5b60ed34e1f95c9b313f3a8fd6b70242c4 Mon Sep 17 00:00:00 2001 From: Nicholas Chmielewski Date: Thu, 16 May 2013 16:05:37 +1000 Subject: [PATCH 1/5] Test that get_by_id methods support ids as symbols --- spec/active_enum/storage/i18n_store_spec.rb | 8 +++++++- spec/active_enum/storage/memory_store_spec.rb | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/spec/active_enum/storage/i18n_store_spec.rb b/spec/active_enum/storage/i18n_store_spec.rb index d4f7033..578eb13 100644 --- a/spec/active_enum/storage/i18n_store_spec.rb +++ b/spec/active_enum/storage/i18n_store_spec.rb @@ -81,11 +81,16 @@ class TestI18nStoreEnum < ActiveEnum::Base; end I18n.locale = :en end - it 'should return the value for a given id' do + it 'should return the value for a given integer id' do store.set 1, 'test' store.get_by_id(1).should == [1, 'Testing'] end + it 'should return the value for a given symbol id' do + store.set :abc, 'test' + store.get_by_id(:abc).should == [:abc, 'Testing'] + end + it 'should return the value with meta for a given id' do store.set 1, 'test', :description => 'meta' store.get_by_id(1).should == [1, 'Testing', { :description => 'meta' }] @@ -93,6 +98,7 @@ class TestI18nStoreEnum < ActiveEnum::Base; end it 'should return nil when id not found' do store.get_by_id(1).should be_nil + store.get_by_id(:abc).should be_nil end it 'should return key when translation missing' do diff --git a/spec/active_enum/storage/memory_store_spec.rb b/spec/active_enum/storage/memory_store_spec.rb index 638f962..0deb4c6 100644 --- a/spec/active_enum/storage/memory_store_spec.rb +++ b/spec/active_enum/storage/memory_store_spec.rb @@ -53,13 +53,19 @@ class TestOtherAREnum < ActiveEnum::Base; end end describe "#get_by_id" do - it 'should return the value for a given id' do + it 'should return the value for a given integer id' do store.set 1, 'test name', :description => 'meta' store.get_by_id(1).should == [1, 'test name', {:description => "meta"}] end + it 'should return the value for a given symbol id' do + store.set :abc, 'test name', :description => 'meta' + store.get_by_id(:abc).should == [:abc, 'test name', {:description => "meta"}] + end + it 'should return nil when id not found' do store.get_by_id(1).should be_nil + store.get_by_id(:abc).should be_nil end end From bb674f018a0d359f334bc551f60e98383e3bb125 Mon Sep 17 00:00:00 2001 From: Nicholas Chmielewski Date: Thu, 16 May 2013 16:10:01 +1000 Subject: [PATCH 2/5] Add context to spec in preparation for new tests --- spec/active_enum/base_spec.rb | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/spec/active_enum/base_spec.rb b/spec/active_enum/base_spec.rb index 98c3df5..52cb427 100644 --- a/spec/active_enum/base_spec.rb +++ b/spec/active_enum/base_spec.rb @@ -161,24 +161,26 @@ class NewEnum < ActiveEnum::Base; end end context "element reference method" do - let(:enum) { - define_enum do - value :id => 1, :name => 'Name 1' - value :id => 2, :name => 'Name 2' - end - } + context 'integer ids' do + let(:enum) { + define_enum do + value :id => 1, :name => 'Name 1' + value :id => 2, :name => 'Name 2' + end + } - it 'should return name when given an id' do - enum[1].should == 'Name 1' - end + it 'should return name when given an id' do + enum[1].should == 'Name 1' + end - it 'should return id when given a name' do - enum['Name 1'].should == 1 - end + it 'should return id when given a name' do + enum['Name 1'].should == 1 + end - it 'should return id when given a symbol of the name' do - enum[:Name_1].should == 1 - enum[:name_1].should == 1 + it 'should return id when given a symbol of the name' do + enum[:Name_1].should == 1 + enum[:name_1].should == 1 + end end end From 3e09cb9703fd42ecb9186504fa076cc59cfbb746 Mon Sep 17 00:00:00 2001 From: Nicholas Chmielewski Date: Thu, 16 May 2013 16:16:14 +1000 Subject: [PATCH 3/5] Add support for ids as symbols --- README.rdoc | 7 +++++ lib/active_enum/base.rb | 27 ++++++++++++------ spec/active_enum/base_spec.rb | 54 ++++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 10 deletions(-) diff --git a/README.rdoc b/README.rdoc index 1b31511..d4a80da 100644 --- a/README.rdoc +++ b/README.rdoc @@ -43,6 +43,13 @@ Define using implicit id values value :name => 'Female' end +Define using symbol ids + + class Sex < ActiveEnum::Base + value :id => :m, :name => 'Male' + value :id => :f, :name => 'Female' + end + Beware that if you change the order of values defined in an enum which don't have explicit ids, then the ids will change. This could corrupt your data if the enum values have been stored in a model record, as they will no longer map to the original enum. diff --git a/lib/active_enum/base.rb b/lib/active_enum/base.rb index 29bf7fb..7af39d4 100644 --- a/lib/active_enum/base.rb +++ b/lib/active_enum/base.rb @@ -55,13 +55,17 @@ def to_select # Access id or name value. Pass an id number to retrieve the name or # a symbol or string to retrieve the matching id. def get(index) - if index.is_a?(Fixnum) + if index.is_a?(Fixnum) || index.is_a?(Symbol) row = store.get_by_id(index) - row[1] if row - else + value = row[1] if row + end + + if (index.is_a?(String) || index.is_a?(Symbol)) && value.nil? row = store.get_by_name(index) - row[0] if row + value = row[0] if row end + + value end alias_method :[], :get @@ -71,12 +75,17 @@ def include?(value) # Access any meta data defined for a given id or name. Returns a hash. def meta(index) - row = if index.is_a?(Fixnum) - store.get_by_id(index) - else - store.get_by_name(index) + if index.is_a?(Fixnum) || index.is_a?(Symbol) + row = store.get_by_id(index) + value = row[2] if row end - row[2] || {} if row + + if (index.is_a?(String) || index.is_a?(Symbol)) && value.nil? + row = store.get_by_name(index) + value = row[2] if row + end + + value || {} end private diff --git a/spec/active_enum/base_spec.rb b/spec/active_enum/base_spec.rb index 52cb427..4d9da79 100644 --- a/spec/active_enum/base_spec.rb +++ b/spec/active_enum/base_spec.rb @@ -95,13 +95,28 @@ class NewEnum < ActiveEnum::Base; end end describe ".meta" do - it 'should return meta values hash for a given index value' do + it 'should return meta values hash for a given integer index value' do enum = define_enum do value :id => 1, :name => 'Name', :description => 'extra' end enum.meta(1).should == {:description => 'extra'} end + it 'should return meta values hash for a given symbol index value' do + enum = define_enum do + value :id => :one, :name => 'Name 1', :description => 'extra' + end + enum.meta(:one).should == {:description => 'extra'} + end + + it 'should match on id before name and return meta values hash' do + enum = define_enum do + value :id => :one, :name => 'Name 1', :description => 'extra' + value :id => :name_1, :name => 'Name 2', :description => 'extra2' + end + enum.meta(:name_1).should == {:description => 'extra2'} + end + it 'should return empty hash for index with no meta defined' do enum = define_enum do value :id => 1, :name => 'Name' @@ -182,6 +197,43 @@ class NewEnum < ActiveEnum::Base; end enum[:name_1].should == 1 end end + + context 'symbol ids' do + let(:enum) { + define_enum do + value :id => :one, :name => 'Name 1' + value :id => :two, :name => 'Name 2' + end + } + + it 'should return name when given an id' do + enum[:one].should == 'Name 1' + end + + it 'should return id when given a name' do + enum['Name 1'].should == :one + end + + it 'should return id when given a symbol of the name' do + enum[:Name_1].should == :one + enum[:name_1].should == :one + end + + context 'ids and names are similar' do + let(:enum) { + define_enum do + value :id => :one, :name => 'two' + value :id => :two, :name => 'three' + end + } + + it 'should match on id before name' do + enum[:one].should == 'two' + enum[:two].should == 'three' + enum[:three].should == :two + end + end + end end describe ".include?" do From d1d2f471726d9ddb2883f627fb58da2a4ed60dd0 Mon Sep 17 00:00:00 2001 From: Nicholas Chmielewski Date: Wed, 22 May 2013 16:06:24 +1000 Subject: [PATCH 4/5] Add tests to make sure that form helpers work with symbol ids --- .../form_helpers/formtastic2_spec.rb | 29 ++++++++++++++++++ .../form_helpers/simple_form_spec.rb | 30 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/spec/active_enum/form_helpers/formtastic2_spec.rb b/spec/active_enum/form_helpers/formtastic2_spec.rb index 7ef3b79..7373b6f 100644 --- a/spec/active_enum/form_helpers/formtastic2_spec.rb +++ b/spec/active_enum/form_helpers/formtastic2_spec.rb @@ -36,6 +36,35 @@ output.should have_xpath('//option[@value=2]', :content => 'Female') end + context 'with ids as symbols' do + before do + reset_class Person do + enumerate :sex do + value :id => :m, :name => 'Male' + value :id => :f, :name => 'Female' + end + end + end + + it "should use enum input type for enumerated attribute" do + output = semantic_form_for(Person.new, :url => people_path) do |f| + concat f.input(:sex) + end + output.should have_selector('select#person_sex') + output.should have_xpath("//option[@value='m']", :content => 'Male') + output.should have_xpath("//option[@value='f']", :content => 'Female') + end + + it "should use explicit :enum input type" do + output = semantic_form_for(Person.new, :url => people_path) do |f| + concat f.input(:sex, :as => :enum) + end + output.should have_selector('select#person_sex') + output.should have_xpath("//option[@value='m']", :content => 'Male') + output.should have_xpath("//option[@value='f']", :content => 'Female') + end + end + it "should not use enum input type if :as option indicates other type" do output = semantic_form_for(Person.new, :url => people_path) do |f| concat f.input(:sex, :as => :string) diff --git a/spec/active_enum/form_helpers/simple_form_spec.rb b/spec/active_enum/form_helpers/simple_form_spec.rb index fd19fb4..eb988fd 100644 --- a/spec/active_enum/form_helpers/simple_form_spec.rb +++ b/spec/active_enum/form_helpers/simple_form_spec.rb @@ -34,6 +34,36 @@ output.should have_xpath('//option[@value=2]', :content => 'Female') end + context 'with ids as symbols' do + before do + controller.stub!(:action_name).and_return('new') + reset_class Person do + enumerate :sex do + value :id => :m, :name => 'Male' + value :id => :f, :name => 'Female' + end + end + end + + it "should use enum input type for enumerated attribute" do + output = simple_form_for(Person.new, :url => people_path) do |f| + concat f.input(:sex) + end + output.should have_selector('select#person_sex') + output.should have_xpath("//option[@value='m']", :content => 'Male') + output.should have_xpath("//option[@value='f']", :content => 'Female') + end + + it "should use explicit :enum input type" do + output = simple_form_for(Person.new, :url => people_path) do |f| + concat f.input(:sex, :as => :enum) + end + output.should have_selector('select#person_sex') + output.should have_xpath("//option[@value='m']", :content => 'Male') + output.should have_xpath("//option[@value='f']", :content => 'Female') + end + end + it "should not use enum input type if :as option indicates other type" do output = simple_form_for(Person.new, :url => people_path) do |f| concat f.input(:sex, :as => :string) From fdd891facb29b14233bcb938cf8c7fd7bc282867 Mon Sep 17 00:00:00 2001 From: Adam Hardiman Date: Fri, 14 Jul 2017 14:07:07 +1000 Subject: [PATCH 5/5] Use Integer instead of Fixnum --- lib/active_enum/acts_as_enum.rb | 2 +- lib/active_enum/base.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/active_enum/acts_as_enum.rb b/lib/active_enum/acts_as_enum.rb index f88fdc5..d6bec9b 100644 --- a/lib/active_enum/acts_as_enum.rb +++ b/lib/active_enum/acts_as_enum.rb @@ -29,7 +29,7 @@ def to_select end def [](index) - if index.is_a?(Fixnum) + if index.is_a?(Integer) v = lookup_by_id(index) v.send(active_enum_options[:name_column]) unless v.blank? else diff --git a/lib/active_enum/base.rb b/lib/active_enum/base.rb index 7af39d4..97092be 100644 --- a/lib/active_enum/base.rb +++ b/lib/active_enum/base.rb @@ -55,7 +55,7 @@ def to_select # Access id or name value. Pass an id number to retrieve the name or # a symbol or string to retrieve the matching id. def get(index) - if index.is_a?(Fixnum) || index.is_a?(Symbol) + if index.is_a?(Integer) || index.is_a?(Symbol) row = store.get_by_id(index) value = row[1] if row end @@ -75,7 +75,7 @@ def include?(value) # Access any meta data defined for a given id or name. Returns a hash. def meta(index) - if index.is_a?(Fixnum) || index.is_a?(Symbol) + if index.is_a?(Integer) || index.is_a?(Symbol) row = store.get_by_id(index) value = row[2] if row end @@ -96,7 +96,7 @@ def id_and_name_and_meta(hash) name = hash.delete(:name) meta = hash return id, name, (meta.empty? ? nil : meta) - elsif hash.keys.first.is_a?(Fixnum) + elsif hash.keys.first.is_a?(Integer) return *Array(hash).first else raise ActiveEnum::InvalidValue, "The value supplied, #{hash}, is not a valid format."