From a9387acfb94fa260cfef9e5c671e900339e9a722 Mon Sep 17 00:00:00 2001 From: Jake Johnson Date: Thu, 19 Nov 2015 12:43:51 -0600 Subject: [PATCH] Support floats and add specs --- lib/model_attribute.rb | 2 +- lib/model_attribute/casts.rb | 2 ++ spec/model_attributes_spec.rb | 22 ++++++++++++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/model_attribute.rb b/lib/model_attribute.rb index 7fe6134..f740f6d 100644 --- a/lib/model_attribute.rb +++ b/lib/model_attribute.rb @@ -4,7 +4,7 @@ require "time" module ModelAttribute - SUPPORTED_TYPES = [:integer, :boolean, :string, :time, :json] + SUPPORTED_TYPES = [:integer, :float, :boolean, :string, :time, :json] def self.extended(base) base.send(:include, InstanceMethods) diff --git a/lib/model_attribute/casts.rb b/lib/model_attribute/casts.rb index f8f1d92..c55f02e 100644 --- a/lib/model_attribute/casts.rb +++ b/lib/model_attribute/casts.rb @@ -10,6 +10,8 @@ def cast(value, type) float = Float(value) raise ArgumentError, "Can't cast #{value.inspect} to an integer without loss of precision" unless int == float int + when :float + Float(value) when :boolean if !!value == value value diff --git a/spec/model_attributes_spec.rb b/spec/model_attributes_spec.rb index db4409f..5a9bc58 100644 --- a/spec/model_attributes_spec.rb +++ b/spec/model_attributes_spec.rb @@ -6,6 +6,7 @@ class User attribute :created_at, :time attribute :profile, :json attribute :reward_points, :integer, default: 0 + attribute :win_rate, :float def initialize(attributes = {}) set_attributes(attributes) @@ -32,14 +33,14 @@ def initialize(attributes = {}) User.attribute :address, :custom_type end.to raise_error(ModelAttribute::UnsupportedTypeError, "Unsupported type :custom_type. " + - "Must be one of :integer, :boolean, :string, :time, :json.") + "Must be one of :integer, :float, :boolean, :string, :time, :json.") end end end describe ".attributes" do it "returns an array of attribute names as symbols" do - expect(User.attributes).to eq([:id, :paid, :name, :created_at, :profile, :reward_points]) + expect(User.attributes).to eq([:id, :paid, :name, :created_at, :profile, :reward_points, :win_rate]) end end @@ -94,6 +95,18 @@ def initialize(attributes = {}) end end + describe "a float attribute (win_rate)" do + it "stores a float" do + user.win_rate = 35.62 + expect(user.win_rate).to eq(35.62) + end + + it "parses a float string" do + user.win_rate = 35.62 + expect(user.win_rate).to eq(35.62) + end + end + describe "a boolean attribute (paid)" do it "is nil when unset" do expect(user.paid).to be_nil @@ -548,7 +561,8 @@ def initialize(attributes = {}) name: "Fred", created_at: "2014-12-25 08:00", paid: true, - profile: {'interests' => ['coding', 'social networks'], 'rank' => 15}) + profile: {'interests' => ['coding', 'social networks'], 'rank' => 15}, + win_rate: 35.62) end it "includes integer attributes as 'name: value'" do @@ -580,7 +594,7 @@ def initialize(attributes = {}) end it "looks like '#'" do - expect(user.inspect).to eq("#[\"coding\", \"social networks\"], \"rank\"=>15}, reward_points: 0>") + expect(user.inspect).to eq("#[\"coding\", \"social networks\"], \"rank\"=>15}, reward_points: 0, win_rate: 35.62>") end end