ohm-contrib 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -48,6 +48,17 @@ Example usage
48
48
  Post.create.created_at
49
49
  Post.create.updated_at
50
50
 
51
+ # Casting example
52
+ class Product
53
+ include Ohm::Typecast
54
+
55
+ attribute :price, :decimal
56
+ attribute :start_of_sale, :time
57
+ attribute :end_of_sale, :time
58
+ attribute :priority, :integer
59
+ attribute :rating, :float
60
+ end
61
+
51
62
  Credits
52
63
  -------
53
64
  Thanks to github user gnrfan for the web validations.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -0,0 +1,48 @@
1
+ require 'bigdecimal'
2
+ require 'time'
3
+ require 'date'
4
+
5
+ module Ohm
6
+ module Typecast
7
+ def self.included(base)
8
+ base.extend Macros
9
+ end
10
+
11
+ module Macros
12
+ def attribute(name, type = :string)
13
+ define_method(name) do
14
+ typecast(read_local(name), type)
15
+ end
16
+
17
+ define_method(:"#{name}=") do |value|
18
+ write_local(name, value && value.to_s)
19
+ end
20
+
21
+ attributes << name unless attributes.include?(name)
22
+ end
23
+ end
24
+
25
+ protected
26
+ def typecast(val, type)
27
+ return val if val.to_s.empty?
28
+
29
+ case type
30
+ when :integer then Integer(val)
31
+ when :float then Float(val)
32
+ when :decimal then BigDecimal(val)
33
+ when :time
34
+ ret = Time.parse(val)
35
+ ret.to_s == val ? ret : val
36
+
37
+ when :date then Date.parse(val)
38
+ when :string then val
39
+ end
40
+
41
+ # All of the casting methods used above raises an ArgumentError
42
+ # if it fails to parse the value properly. If this happens,
43
+ # the least surprising behavior is to return the original value
44
+ rescue ArgumentError
45
+ val
46
+ end
47
+ end
48
+ end
data/lib/ohm/contrib.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Ohm
2
2
  module Contrib
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.3'
4
4
  end
5
5
 
6
6
  autoload :Boundaries, "ohm/contrib/boundaries"
@@ -8,4 +8,5 @@ module Ohm
8
8
  autoload :ToHash, "ohm/contrib/to_hash"
9
9
  autoload :WebValidations, "ohm/contrib/web_validations"
10
10
  autoload :NumberValidations, "ohm/contrib/number_validations"
11
+ autoload :Typecast, "ohm/contrib/typecast"
11
12
  end
data/ohm-contrib.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ohm-contrib}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cyril David"]
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
  "lib/ohm/contrib/number_validations.rb",
29
29
  "lib/ohm/contrib/timestamping.rb",
30
30
  "lib/ohm/contrib/to_hash.rb",
31
+ "lib/ohm/contrib/typecast.rb",
31
32
  "lib/ohm/contrib/web_validations.rb",
32
33
  "ohm-contrib.gemspec",
33
34
  "test/helper.rb",
@@ -36,6 +37,7 @@ Gem::Specification.new do |s|
36
37
  "test/test_ohm_number_validations.rb",
37
38
  "test/test_ohm_timestamping.rb",
38
39
  "test/test_ohm_to_hash.rb",
40
+ "test/test_ohm_typecast.rb",
39
41
  "test/test_ohm_web_validations.rb"
40
42
  ]
41
43
  s.homepage = %q{http://github.com/sinefunc/ohm-contrib}
@@ -50,6 +52,7 @@ Gem::Specification.new do |s|
50
52
  "test/test_ohm_number_validations.rb",
51
53
  "test/test_ohm_timestamping.rb",
52
54
  "test/test_ohm_to_hash.rb",
55
+ "test/test_ohm_typecast.rb",
53
56
  "test/test_ohm_web_validations.rb"
54
57
  ]
55
58
 
@@ -30,5 +30,10 @@ class TestOhmContrib < Test::Unit::TestCase
30
30
  Ohm::NumberValidations
31
31
  end
32
32
  end
33
-
33
+
34
+ test "autoloading of Typecast" do
35
+ assert_nothing_raised NameError, LoadError do
36
+ Ohm::Typecast
37
+ end
38
+ end
34
39
  end
@@ -0,0 +1,159 @@
1
+ require "helper"
2
+
3
+ class TestOhmTypecast < Test::Unit::TestCase
4
+ context "decimal typecasting" do
5
+ class Product < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :price, :decimal
9
+ end
10
+
11
+ should "properly preserve the right precision" do
12
+ product = Product.create(:price => 0.0001)
13
+ product = Product[product.id]
14
+ sum = 0
15
+ 1_000.times { sum += product.price }
16
+
17
+ assert_equal 0.1, sum
18
+ end
19
+ end
20
+
21
+ context "time typecasting" do
22
+ class Product < Ohm::Model
23
+ include Ohm::Typecast
24
+
25
+ attribute :start_of_sale, :time
26
+ end
27
+
28
+ test "read / write" do
29
+ @time = Time.now.utc
30
+ product = Product.create(:start_of_sale => @time)
31
+ product = Product[product.id]
32
+
33
+ assert_equal @time, product.start_of_sale
34
+ end
35
+
36
+ test "the retrieved value is a Time object" do
37
+ @time = Time.now.utc
38
+ product = Product.create(:start_of_sale => @time)
39
+ product = Product[product.id]
40
+
41
+ assert_instance_of Time, product.start_of_sale
42
+ end
43
+
44
+ test "an invalid string" do
45
+ product = Product.create(:start_of_sale => "invalid time")
46
+ product = Product[product.id]
47
+
48
+ assert_equal "invalid time", product.start_of_sale
49
+ end
50
+
51
+ test "when nil" do
52
+ product = Product.new(:start_of_sale => nil)
53
+ assert_nil product.start_of_sale
54
+ end
55
+
56
+ test "when empty string" do
57
+ product = Product.new(:start_of_sale => "")
58
+ assert_equal "", product.start_of_sale
59
+ end
60
+ end
61
+
62
+ context "date typecasting" do
63
+ class Product < Ohm::Model
64
+ include Ohm::Typecast
65
+
66
+ attribute :date_bought, :date
67
+ end
68
+
69
+ test "read / write" do
70
+ @date = Date.today
71
+ product = Product.create(:date_bought => @date)
72
+ product = Product[product.id]
73
+
74
+ assert_equal @date, product.date_bought
75
+ end
76
+
77
+ test "the retrieved value is a Date object" do
78
+ @date = Date.today
79
+ product = Product.create(:date_bought => @date)
80
+ product = Product[product.id]
81
+
82
+ assert_instance_of Date, product.date_bought
83
+ end
84
+
85
+ test "assigning a string which is not a valid date before persisting" do
86
+ product = Product.create(:date_bought => "Bla Bla")
87
+
88
+ assert_equal "Bla Bla", product.date_bought
89
+ end
90
+
91
+ test "when nil" do
92
+ assert_nil Product.new.date_bought
93
+ end
94
+
95
+ test "empty string" do
96
+ assert_equal "", Product.new(:date_bought => "").date_bought
97
+ end
98
+ end
99
+
100
+ context "integer typecasting" do
101
+ class Product < Ohm::Model
102
+ include Ohm::Typecast
103
+
104
+ attribute :stock_count, :integer
105
+ end
106
+
107
+ test "when nil" do
108
+ assert_nil Product.new(:stock_count => nil).stock_count
109
+ end
110
+
111
+ test "when empty string" do
112
+ assert_equal "", Product.new(:stock_count => "").stock_count
113
+ end
114
+
115
+ test "when unparseable" do
116
+ assert_equal "FooBar", Product.new(:stock_count => "FooBar").stock_count
117
+ end
118
+
119
+ test "when a float" do
120
+ assert_equal '1.0', Product.new(:stock_count => "1.0").stock_count
121
+ end
122
+
123
+ test "when a real int" do
124
+ assert_equal 1, Product.new(:stock_count => '1').stock_count
125
+ end
126
+ end
127
+
128
+ context "float typecasting" do
129
+ class Product < Ohm::Model
130
+ include Ohm::Typecast
131
+
132
+ attribute :vat, :float
133
+ end
134
+
135
+ test "when nil" do
136
+ assert_nil Product.new(:vat => nil).vat
137
+ end
138
+
139
+ test "when empty string" do
140
+ assert_equal "", Product.new(:vat => "").vat
141
+ end
142
+
143
+ test "when unparseable" do
144
+ assert_equal "FooBar", Product.new(:vat => "FooBar").vat
145
+ end
146
+
147
+ test "when a float" do
148
+ assert_equal 1.0, Product.new(:vat => "1.0").vat
149
+ end
150
+
151
+ test "when an int" do
152
+ assert_equal 1.0, Product.new(:vat => '1').vat
153
+ end
154
+
155
+ test "when a .12 value" do
156
+ assert_equal 0.12, Product.new(:vat => ".12").vat
157
+ end
158
+ end
159
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cyril David
@@ -86,6 +86,7 @@ files:
86
86
  - lib/ohm/contrib/number_validations.rb
87
87
  - lib/ohm/contrib/timestamping.rb
88
88
  - lib/ohm/contrib/to_hash.rb
89
+ - lib/ohm/contrib/typecast.rb
89
90
  - lib/ohm/contrib/web_validations.rb
90
91
  - ohm-contrib.gemspec
91
92
  - test/helper.rb
@@ -94,6 +95,7 @@ files:
94
95
  - test/test_ohm_number_validations.rb
95
96
  - test/test_ohm_timestamping.rb
96
97
  - test/test_ohm_to_hash.rb
98
+ - test/test_ohm_typecast.rb
97
99
  - test/test_ohm_web_validations.rb
98
100
  has_rdoc: true
99
101
  homepage: http://github.com/sinefunc/ohm-contrib
@@ -132,4 +134,5 @@ test_files:
132
134
  - test/test_ohm_number_validations.rb
133
135
  - test/test_ohm_timestamping.rb
134
136
  - test/test_ohm_to_hash.rb
137
+ - test/test_ohm_typecast.rb
135
138
  - test/test_ohm_web_validations.rb