# -*- coding: utf-8 -*- require 'spec_helper' # # Test model class User < ActiveRecord::Base symbolize :other symbolize :language, :in => [:pt, :en] symbolize :sex, :in => [true, false], :scopes => true symbolize :status , :in => [:active, :inactive], :i18n => false, :capitalize => true, :scopes => :shallow, :methods => true symbolize :so, :allow_blank => true, :in => { :linux => 'Linux', :mac => 'Mac OS X', :win => 'Videogame' }, :scopes => true symbolize :gui, :allow_blank => true, :in => [:cocoa, :qt, :gtk], :i18n => false symbolize :karma, :in => %w{ good bad ugly}, :methods => true, :i18n => false, :allow_nil => true symbolize :cool, :in => [true, false], :scopes => true symbolize :role, :in => [:reader, :writer, :some_existing_attr], :i18n => false, :methods => true, :default => :reader symbolize :country, :in => [:us, :gb, :pt, :ru], :capitalize => true, :i18n => false # note: the default value is provided in db migration has_many :extras, :dependent => :destroy, :class_name => "UserExtra" has_many :access, :dependent => :destroy, :class_name => "UserAccess" end class UserSkill < ActiveRecord::Base symbolize :kind, :in => [:agility, :magic] end class UserExtra < ActiveRecord::Base symbolize :key, :in => [:one, :another] end class Permission < ActiveRecord::Base validates_presence_of :name symbolize :kind, :in => [:temp, :perm], :default => :perm symbolize :lvl, :in => (1..9).to_a, :i18n => false#, :default => 1 end class PermissionSubclass < Permission symbolize :sub_lvl end describe "Symbolize" do it "should respond to symbolize" do expect(ActiveRecord::Base).to respond_to :symbolize end it "should have a valid blueprint" do # Test records u = User.create(:name => 'Bob' , :other => :bar,:status => :inactive, :so => :mac, :gui => :gtk, :language => :en, :sex => false, :cool => false) expect(u.errors.messages).to be_blank end it "should work nice with default values from active model" do u = User.create(:name => 'Niu' , :other => :bar, :so => :mac, :gui => :gtk, :language => :en, :sex => false, :cool => false) expect(u.errors.messages).to be_blank expect(u.status).to eql(:active) expect(u).to be_active end describe ".symbolized_attributes" do it "returns the symbolized attribute for the class" do expect(UserExtra.symbolized_attributes).to eq ['key'] expect(Permission.symbolized_attributes).to match_array ['kind', 'lvl'] expect(PermissionSubclass.symbolized_attributes).to match_array ['kind', 'lvl', 'sub_lvl'] end end describe "User Instantiated" do subject { User.create(:name => 'Anna', :other => :fo, :status => status, :so => so, :gui => :qt, :language => :pt, :sex => true, :cool => true) } let(:status) { :active } let(:so) { :linux } describe "test_symbolize_string" do let(:status) { 'inactive' } describe '#status' do subject { super().status } it { is_expected.to eq(:inactive) } end # @user.status_before_type_cast.should eql(:inactive) # @user.read_attribute(:status).should eql('inactive') end describe "test_symbolize_symbol" do describe '#status' do subject { super().status } it { is_expected.to eq(:active) } end describe '#status_before_type_cast' do subject { super().status_before_type_cast } it { is_expected.to eq(:active) } end # @user.read_attribute(:status).should eql('active') end describe "should work nice with numbers" do let(:status) { 43 } describe '#status' do subject { super().status } it { is_expected.to be_present } end # @user.status_before_type_cast.should be_nil # @user.read_attribute(:status).should be_nil end describe "should acts nice with nil" do let(:status) { nil } describe '#status' do subject { super().status } it { is_expected.to be_nil } end describe '#status_before_type_cast' do subject { super().status_before_type_cast } it { is_expected.to be_nil } end it { expect(subject.read_attribute(:status)).to be_nil } end describe "should acts nice with blank" do let(:status) { "" } describe '#status' do subject { super().status } it { is_expected.to be_nil } end describe '#status_before_type_cast' do subject { super().status_before_type_cast } it { is_expected.to be_nil } end it { expect(subject.read_attribute(:status)).to be_nil } end it "should not validates other" do subject.other = nil expect(subject).to be_valid subject.other = "" expect(subject).to be_valid end it "should get the correct values" do expect(User.get_status_values).to eql([["Active", :active],["Inactive", :inactive]]) expect(User::STATUS_VALUES).to eql({:inactive=>"Inactive", :active=>"Active"}) end it "should get the values for RailsAdmin" do expect(User.status_enum).to eql([["Active", :active],["Inactive", :inactive]]) end describe "test_symbolize_humanize" do describe '#status_text' do subject { super().status_text } it { is_expected.to eql("Active") } end end it "should get the correct values" do expect(User.get_gui_values).to match_array([["cocoa", :cocoa], ["qt", :qt], ["gtk", :gtk]]) expect(User::GUI_VALUES).to eql({:cocoa=>"cocoa", :qt=>"qt", :gtk=>"gtk"}) end describe "test_symbolize_humanize" do describe '#gui_text' do subject { super().gui_text } it { is_expected.to eql("qt") } end end it "should get the correct values" do expect(User.get_so_values).to match_array([["Linux", :linux], ["Mac OS X", :mac], ["Videogame", :win]]) expect(User::SO_VALUES).to eql({:linux => "Linux", :mac => "Mac OS X", :win => "Videogame"}) end describe "test_symbolize_humanize" do describe '#so_text' do subject { super().so_text } it { is_expected.to eql("Linux") } end end describe "test_symbolize_humanize" do let(:so) { :mac } describe '#so_text' do subject { super().so_text } it { is_expected.to eql("Mac OS X") } end end it "should stringify" do expect(subject.other_text).to eql("fo") subject.other = :foo expect(subject.other_text).to eql("foo") end describe "should validate status" do let(:status) { nil } it { is_expected.not_to be_valid } it 'has 1 error' do expect(subject.errors.size).to eq(1) end end it "should not validate so" do subject.so = nil expect(subject).to be_valid end it "test_symbols_with_weird_chars_quoted_id" do subject.status = :"weird'; chars" expect(subject.status_before_type_cast).to eql(:"weird'; chars") end it "should work fine through relations" do subject.extras.create(:key => :one) expect(UserExtra.first.key).to eql(:one) end it "should play fine with null db columns" do new_extra = subject.extras.build expect(new_extra).not_to be_valid end it "should play fine with null db columns" do new_extra = subject.extras.build expect(new_extra).not_to be_valid end describe "i18n" do it "should test i18n ones" do expect(subject.language_text).to eql("Português") end it "should get the correct values" do expect(User.get_language_values).to match_array([["Português", :pt], ["Inglês", :en]]) end it "should get the correct values" do expect(User::LANGUAGE_VALUES).to eql({:pt=>"pt", :en=>"en"}) end it "should test boolean" do expect(subject.sex_text).to eql("Feminino") subject.sex = false expect(subject.sex_text).to eql('Masculino') end it "should get the correct values" do expect(User.get_sex_values).to eql([["Feminino", true],["Masculino", false]]) end it "should get the correct values" do expect(User::SEX_VALUES).to eql({true=>"true", false=>"false"}) end it "should translate a multiword class" do @skill = UserSkill.create(:kind => :magic) expect(@skill.kind_text).to eql("Mágica") end it "should return nil if there's no value" do @skill = UserSkill.create(:kind => nil) expect(@skill.kind_text).to be_nil end end describe "Methods" do it "should play nice with other stuff" do expect(subject.karma).to be_nil expect(User::KARMA_VALUES).to eql({:bad => "bad", :ugly => "ugly", :good => "good"}) end it "should provide a boolean method" do expect(subject).not_to be_good subject.karma = :ugly expect(subject).to be_ugly end it "should work" do subject.karma = "good" expect(subject).to be_good expect(subject).not_to be_bad end end describe "Changes" do it "is dirty if you change the attribute value" do expect(subject.language).to eq(:pt) expect(subject.language_changed?).to be false return_value = subject.language = :en expect(return_value).to eq(:en) expect(subject.language_changed?).to be true end it "is not dirty if you set the attribute value to the same value" do expect(subject.language).to eq(:pt) expect(subject.language_changed?).to be false return_value = subject.language = :pt expect(return_value).to eq(:pt) expect(subject.language_changed?).to be false end it "is not dirty if you set the attribute value to the same value (string)" do expect(subject.language).to eq(:pt) expect(subject.language_changed?).to be false return_value = subject.language = 'pt' expect(subject.language_changed?).to be false end it "is not dirty if you set the default attribute value to the same value" do user = User.create!(:language => :pt, :sex => true, :cool => true) expect(user.status).to eq(:active) expect(user).not_to be_changed user.status = :active expect(user).not_to be_changed end it "is not dirty if you set the default attribute value to the same value (string)" do user = User.create!(:language => :pt, :sex => true, :cool => true) expect(user.status).to eq(:active) expect(user).not_to be_changed user.status = 'active' expect(user).not_to be_changed end end end describe "more tests on Permission" do it "should use default value on object build" do expect(Permission.new.kind).to eql(:perm) end it "should not interfer on create" do Permission.create!(:name => "p7", :kind =>:temp, :lvl => 7) expect(Permission.find_by_name("p7").kind).to eql(:temp) end it "should work on create" do pm = Permission.new(:name => "p7", :lvl => 7) expect(pm).to be_valid expect(pm.save).to be true end it "should work on create" do Permission.create!(:name => "p8", :lvl => 9) expect(Permission.find_by_name("p8").kind).to eql(:perm) end it "should work on edit" do Permission.create!(:name => "p8", :lvl => 9) pm = Permission.find_by_name("p8") pm.kind = :temp pm.save expect(Permission.find_by_name("p8").kind).to eql(:temp) end it "should work with default values" do pm = Permission.new(:name => "p9") pm.lvl = 9 pm.save expect(Permission.find_by_name("p9").lvl.to_i).to eql(9) end end describe "Named Scopes" do before do @anna = User.create(:name => 'Anna', :other => :fo, :status => :active , :so => :linux, :gui => :qt, :language => :pt, :sex => true, :cool => true) @mary = User.create(:name => 'Mary', :other => :fo, :status => :inactive, :so => :mac, :language => :pt, :sex => true, :cool => true) end it "test_symbolized_finder" do expect(User.where({ :status => :inactive }).all.map(&:name)).to eql(['Mary']) end it "test_symbolized_scoping" do User.where({ :status => :inactive }).scoping do expect(User.all.map(&:name)).to eql(['Mary']) end end it "should have main named scope" do expect(User.inactive).to eq([@mary]) end it "should have other to test better" do expect(User.so(:linux)).to eq([@anna]) end # it "should have 'with' helper" do # User.with_sex.should == [@anna] # end # it "should have 'without' helper" do # User.without_sex.should == [@bob] # end # it "should have 'attr_name' helper" do # User.cool.should == [@anna] # end # it "should have 'not_attr_name' helper" do # User.not_cool.should == [@bob] # end end describe ": Default Value" do before(:each) do @user = User.new(:name => 'Anna', :other => :fo, :status => :active , :so => :linux, :gui => :qt, :language => :pt, :sex => true, :cool => true) end it "should be considered during validation" do @user.valid? expect(@user.errors.full_messages).to eq([]) end it "should be taken from the DB schema definition" do expect(@user.country).to eq(:pt) expect(@user.country_text).to eq("Pt") end it "should be applied to new, just saved, and reloaded objects, and also play fine with :methods option" do expect(@user.role).to eq(:reader) expect(@user.role_text).to eq("reader") expect(@user).to be_reader @user.save! expect(@user.role).to eq(:reader) expect(@user).to be_reader @user.reload expect(@user.role).to eq(:reader) expect(@user).to be_reader end it "should be overridable" do @user.role = :writer expect(@user.role).to eq(:writer) expect(@user).to be_writer @user.save! expect(@user.role).to eq(:writer) expect(@user).to be_writer @user.reload expect(@user.role).to eq(:writer) expect(@user).to be_writer end # This feature is for the next major version (b/o the compatibility problem) it "should detect name collision caused by ':methods => true' option" do pending 'next major version' expect { User.class_eval do # 'reader?' method is already defined, so the line below should raise an error symbolize :some_attr, :in => [:reader, :guest], :methods => true end }.to raise_error(ArgumentError) end end end