ohm-contrib 0.0.31 → 0.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. data/LICENSE +2 -1
  2. data/README.markdown +2 -1
  3. data/Rakefile +4 -53
  4. data/lib/ohm/contrib.rb +2 -2
  5. data/lib/ohm/contrib/boundaries.rb +1 -0
  6. data/lib/ohm/contrib/callbacks.rb +5 -4
  7. data/lib/ohm/contrib/date_validations.rb +2 -1
  8. data/lib/ohm/contrib/extra_validations.rb +1 -0
  9. data/lib/ohm/contrib/length_validations.rb +1 -0
  10. data/lib/ohm/contrib/locking.rb +2 -1
  11. data/lib/ohm/contrib/lunar_macros.rb +5 -4
  12. data/lib/ohm/contrib/number_validations.rb +1 -0
  13. data/lib/ohm/contrib/slug.rb +1 -0
  14. data/lib/ohm/contrib/timestamping.rb +1 -0
  15. data/lib/ohm/contrib/typecast.rb +1 -0
  16. data/lib/ohm/contrib/web_validations.rb +2 -1
  17. data/test/autoload_test.rb +19 -0
  18. data/test/boundaries_test.rb +45 -0
  19. data/test/callbacks_lint.rb +105 -0
  20. data/test/date_validations_test.rb +29 -0
  21. data/test/helper.rb +19 -10
  22. data/test/instance_callbacks_test.rb +45 -0
  23. data/test/length_validations_test.rb +31 -0
  24. data/test/lunar_macros_test.rb +146 -0
  25. data/test/macro_callbacks_test.rb +57 -0
  26. data/test/membership_validation_test.rb +31 -0
  27. data/test/number_validations_test.rb +37 -0
  28. data/test/slug_test.rb +30 -0
  29. data/test/timestamping_test.rb +32 -0
  30. data/test/typecast_array_test.rb +154 -0
  31. data/test/typecast_boolean_test.rb +43 -0
  32. data/test/typecast_date_test.rb +77 -0
  33. data/test/typecast_decimal_test.rb +77 -0
  34. data/test/typecast_float_test.rb +52 -0
  35. data/test/typecast_hash_test.rb +117 -0
  36. data/test/typecast_integer_test.rb +66 -0
  37. data/test/typecast_string_test.rb +38 -0
  38. data/test/typecast_time_test.rb +67 -0
  39. data/test/typecast_timezone_test.rb +37 -0
  40. data/test/web_validations_test.rb +79 -0
  41. metadata +47 -56
  42. data/.document +0 -5
  43. data/.gitignore +0 -25
  44. data/VERSION +0 -1
  45. data/lib/ohm/contrib/to_hash.rb +0 -39
  46. data/ohm-contrib.gemspec +0 -103
  47. data/test/test_ohm_boundaries.rb +0 -74
  48. data/test/test_ohm_contrib.rb +0 -70
  49. data/test/test_ohm_contrib_callbacks.rb +0 -375
  50. data/test/test_ohm_date_validations.rb +0 -30
  51. data/test/test_ohm_extra_validations.rb +0 -32
  52. data/test/test_ohm_length_validations.rb +0 -32
  53. data/test/test_ohm_lunar_macros.rb +0 -165
  54. data/test/test_ohm_number_validations.rb +0 -59
  55. data/test/test_ohm_slug.rb +0 -29
  56. data/test/test_ohm_timestamping.rb +0 -64
  57. data/test/test_ohm_to_hash.rb +0 -67
  58. data/test/test_ohm_typecast.rb +0 -707
  59. data/test/test_ohm_web_validations.rb +0 -114
@@ -0,0 +1,154 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :addresses, Array
9
+
10
+ def array
11
+ Array.new
12
+ end
13
+
14
+ def top_level_array
15
+ Array
16
+ end
17
+ end
18
+
19
+ test "importing" do
20
+ assert [] == Ohm::Types::Array[nil]
21
+ assert [] == Ohm::Types::Array[""]
22
+ assert [] == Ohm::Types::Array[[]]
23
+
24
+ assert ['a', 'b', 'c', 'd'] == Ohm::Types::Array[['a', 'b', 'c', 'd']]
25
+ end
26
+
27
+ test "exporting / dumping" do
28
+ assert "[]" == Ohm::Types::Array[nil].to_s
29
+ assert "[]" == Ohm::Types::Array[""].to_s
30
+ assert "[]" == Ohm::Types::Array[[]].to_s
31
+
32
+ assert %q{["a","b","c","d"]} == Ohm::Types::Array[['a', 'b', 'c', 'd']].to_s
33
+ end
34
+
35
+ test "still able to get top level methods" do
36
+ assert [] == Post.new.array
37
+ assert Array == Post.new.top_level_array
38
+ end
39
+
40
+ test "handles nil case correctly" do
41
+ post = Post.create(:addresses => nil)
42
+ assert [] == post.addresses
43
+
44
+ post = Post[post.id]
45
+ assert [] == post.addresses
46
+ end
47
+
48
+ test "handles empty string case correctly" do
49
+ post = Post.create(:addresses => "")
50
+ assert [] == post.addresses
51
+
52
+ post = Post[post.id]
53
+ assert [] == post.addresses
54
+ end
55
+
56
+ test "handles populated arrays" do
57
+ addresses = [{"city" => "Singapore", "country" => "SG"},
58
+ {"city" => "Manila", "country" => "PH"}]
59
+
60
+ post = Post.create(:addresses => addresses)
61
+ assert addresses == post.addresses
62
+
63
+ post = Post[post.id]
64
+ assert addresses == post.addresses
65
+ end
66
+
67
+ class AddressArr < Class.new(Struct.new(:city, :country))
68
+ def to_json(*args)
69
+ [city, country].to_json(*args)
70
+ end
71
+ end
72
+
73
+ test "handles an arbitrary class as an element of the array" do
74
+ addresses = [AddressArr.new("Singapore", "SG"),
75
+ AddressArr.new("Philippines", "PH")]
76
+
77
+ post = Post.create(:addresses => addresses)
78
+ assert [['Singapore', 'SG'], ['Philippines', 'PH']] == post.addresses
79
+
80
+ post = Post[post.id]
81
+ assert [['Singapore', 'SG'], ['Philippines', 'PH']] == post.addresses
82
+ end
83
+
84
+ test "allows for array operations" do
85
+ addresses = [{"city" => "Singapore", "country" => "SG"},
86
+ {"city" => "Manila", "country" => "PH"}]
87
+
88
+
89
+ post = Post.create(:addresses => addresses)
90
+ assert 2 == post.addresses.size
91
+
92
+ expected = addresses + [{"city" => "Hong Kong", "country" => "ZN"}]
93
+ actual = post.addresses.push({"city" => "Hong Kong", "country" => "ZN"})
94
+
95
+ assert expected == actual
96
+
97
+ post = Post[post.id]
98
+ assert 2 == post.addresses.size
99
+
100
+ expected = addresses + [{"city" => "Hong Kong", "country" => "ZN"}]
101
+ actual = post.addresses.push({ "city" => "Hong Kong", "country" => "ZN" })
102
+
103
+ assert expected == actual
104
+ end
105
+
106
+ test "looping! and other enumerablems" do
107
+ array = [1, 2, 3]
108
+ post = Post.create(:addresses => array)
109
+
110
+ total = 0
111
+ post.addresses.each { |e| total += e }
112
+ assert 6 == total
113
+
114
+ post = Post[post.id]
115
+ total = 0
116
+ post.addresses.each { |e| total += e }
117
+ assert 6 == total
118
+ end
119
+
120
+ test "handles mutation" do
121
+ post = Post.create(:addresses => [1, 2, 3])
122
+
123
+ post.addresses.push(4, 5, 6)
124
+ post.save
125
+
126
+ assert [1, 2, 3, 4, 5, 6] == post.addresses
127
+
128
+ post = Post[post.id]
129
+ assert [1, 2, 3, 4, 5, 6] == post.addresses
130
+ end
131
+
132
+ test "raises when trying to assign a non-array" do
133
+ assert_raise TypeError do
134
+ Post.new(:addresses => {})
135
+ end
136
+
137
+ assert_raise TypeError do
138
+ Post.new(:addresses => AddressArr.new)
139
+ end
140
+ end
141
+
142
+ test "inspecting" do
143
+ post = Post.create(:addresses => [{ "address1" => "#456",
144
+ "city" => "Singapore",
145
+ "country" => "SG" }])
146
+
147
+ expected = %q{[{"address1":"#456","city":"Singapore","country":"SG"}]}
148
+
149
+ assert expected == post.addresses.inspect
150
+
151
+ post.addresses = 'FooBar'
152
+ assert %{"\\\"FooBar\\\""} == post.addresses.inspect
153
+ end
154
+
@@ -0,0 +1,43 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class User < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :is_admin, Boolean
9
+ end
10
+
11
+ test "empty is nil" do
12
+ assert nil == User.new.is_admin
13
+
14
+ u = User.create
15
+ u = User[u.id]
16
+
17
+ assert nil == User.new.is_admin
18
+ end
19
+
20
+ test "false, 0, '0' is false" do
21
+ [false, 0, '0'].each do |val|
22
+ assert false == User.new(:is_admin => val).is_admin
23
+ end
24
+
25
+ [false, 0, '0'].each do |val|
26
+ u = User.create(:is_admin => val)
27
+ u = User[u.id]
28
+ assert false == u.is_admin
29
+ end
30
+ end
31
+
32
+ test "true, 1, '1' is true" do
33
+ [true, 1, '1'].each do |val|
34
+ assert true == User.new(:is_admin => val).is_admin
35
+ end
36
+
37
+ [true, 1, '1'].each do |val|
38
+ u = User.create(:is_admin => val)
39
+ u = User[u.id]
40
+ assert true == u.is_admin
41
+ end
42
+ end
43
+
@@ -0,0 +1,77 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :created_on, Date
9
+
10
+ def today
11
+ ::Date.today
12
+ end
13
+
14
+ def date
15
+ Date
16
+ end
17
+
18
+ def may_5
19
+ Date.new(2010, 05, 05)
20
+ end
21
+
22
+ def base_today
23
+ Date.today
24
+ end
25
+ end
26
+
27
+ test "still able to get top level methods" do
28
+ assert Date.today == Post.new.base_today
29
+ end
30
+
31
+ test "allows instantiation of dates" do
32
+ assert Date.new(2010, 05, 05) == Post.new.may_5
33
+ end
34
+
35
+ test "handles nil case correctly" do
36
+ post = Post.create(:created_on => nil)
37
+ post = Post[post.id]
38
+
39
+ assert nil == post.created_on
40
+ end
41
+
42
+ test "handles empty string case correctly" do
43
+ post = Post.create(:created_on => "")
44
+ post = Post[post.id]
45
+
46
+ assert "" == post.created_on.to_s
47
+ end
48
+
49
+ test "allows for real time operations" do
50
+ post = Post.create(:created_on => "2010-05-10")
51
+ post = Post[post.id]
52
+
53
+ assert post.created_on.respond_to?(:strftime)
54
+ assert "2010-05-10" == post.created_on.strftime('%Y-%m-%d')
55
+ end
56
+
57
+ test "raises when trying to do date operations on a non-date" do
58
+ post = Post.create(:created_on => "FooBar")
59
+ post = Post[post.id]
60
+
61
+ assert_raise ArgumentError do
62
+ post.created_on.strftime("%Y")
63
+ end
64
+ end
65
+
66
+ test "still able to access Date" do
67
+ assert Date.today == Post.new.today
68
+ end
69
+
70
+ test "inspecting" do
71
+ post = Post.create(:created_on => Date.new(2010, 5, 5))
72
+ assert '"2010-05-05"' == post.created_on.inspect
73
+
74
+ post.created_on = 'FooBar'
75
+ assert '"FooBar"' == post.created_on.inspect
76
+ end
77
+
@@ -0,0 +1,77 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :price, Decimal
9
+ end
10
+
11
+ test "handles nil case correctly" do
12
+ post = Post.create(:price => nil)
13
+ post = Post[post.id]
14
+
15
+ assert nil == post.price
16
+ end
17
+
18
+ test "handles empty string case correctly" do
19
+ post = Post.create(:price => "")
20
+ post = Post[post.id]
21
+
22
+ assert "" == post.price.to_s
23
+ end
24
+
25
+ test "allows for real arithmetic" do
26
+ post = Post.create(:price => "0.01")
27
+ post = Post[post.id]
28
+
29
+ assert 0.02 == post.price + post.price
30
+ assert 0.0 == post.price - post.price
31
+ assert 0.0001 == post.price * post.price
32
+ assert 1.0 == post.price / post.price
33
+ end
34
+
35
+ test "is accurate accdg to the decimal spec" do
36
+ post = Post.create(:price => "0.0001")
37
+ post = Post[post.id]
38
+
39
+ sum = 0
40
+ 1_000.times { sum += post.price }
41
+ assert 0.1 == sum
42
+ end
43
+
44
+ test "using += with price" do
45
+ post = Post.create(:price => "0.0001")
46
+ post = Post[post.id]
47
+
48
+ post.price += 1
49
+ assert 1.0001 == post.price.to_f
50
+ end
51
+
52
+ test "assigning a raw BigDecimal" do
53
+ post = Post.create(:price => BigDecimal("399.50"))
54
+ post = Post[post.id]
55
+
56
+ assert post.price.to_s.kind_of?(String)
57
+ end
58
+
59
+ test "equality and comparable matching" do
60
+ post = Post.create(:price => "399.50")
61
+ assert (post.price == "399.50")
62
+ assert (post.price < 399.51)
63
+ assert (post.price > 399.49)
64
+ assert (post.price <= 399.50)
65
+ assert (post.price <= 399.51)
66
+ assert (post.price >= 399.50)
67
+ assert (post.price >= 399.49)
68
+ end
69
+
70
+ test "inspecting a Decimal" do
71
+ post = Post.new(:price => 399.50)
72
+ assert '"399.5"' == post.price.inspect
73
+
74
+ post.price = 'FooBar'
75
+ assert '"FooBar"' == post.price.inspect
76
+ end
77
+
@@ -0,0 +1,52 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :price, Float
9
+ end
10
+
11
+ test "handles nil case correctly" do
12
+ post = Post.create(:price => nil)
13
+ post = Post[post.id]
14
+
15
+ assert nil == post.price
16
+ end
17
+
18
+ test "handles empty string case correctly" do
19
+ post = Post.create(:price => "")
20
+ post = Post[post.id]
21
+
22
+ assert "" == post.price.to_s
23
+ end
24
+
25
+ test "allows for real arithmetic" do
26
+ post = Post.create(:price => "3")
27
+ post = Post[post.id]
28
+
29
+ assert 6.0 == post.price + post.price
30
+ assert 0.0 == post.price - post.price
31
+ assert 9.0 == post.price * post.price
32
+ assert 1.0 == post.price / post.price
33
+ end
34
+
35
+ test "raises when trying to do arithmetic ops on a non-float" do
36
+
37
+ post = Post.create(:price => "FooBar")
38
+ post = Post[post.id]
39
+
40
+ assert_raise ArgumentError do
41
+ post.price * post.price
42
+ end
43
+ end
44
+
45
+ test "inspecting" do
46
+ post = Post.new(:price => "12345.67890")
47
+ assert '"12345.67890"' == post.price.inspect
48
+
49
+ post.price = 'FooBar'
50
+ assert '"FooBar"' == post.price.inspect
51
+ end
52
+
@@ -0,0 +1,117 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Typecast
7
+
8
+ attribute :address, Hash
9
+
10
+ def hash
11
+ Hash.new
12
+ end
13
+
14
+ def top_level_hash
15
+ Hash
16
+ end
17
+ end
18
+
19
+ test "importing" do
20
+ assert Hash.new == Ohm::Types::Hash[nil]
21
+ assert Hash.new == Ohm::Types::Hash[""]
22
+ assert Hash.new == Ohm::Types::Hash[{}]
23
+
24
+ expected = Hash[:a => "b", :c => "d"]
25
+ assert expected == Ohm::Types::Hash[{ :a => "b", :c => "d" }]
26
+ end
27
+
28
+ test "exporting / dumping" do
29
+ assert "{}" == Ohm::Types::Hash[nil].to_s
30
+ assert "{}" == Ohm::Types::Hash[""].to_s
31
+ assert "{}" == Ohm::Types::Hash[{}].to_s
32
+
33
+ expected = %q{{"a":"b","c":"d"}}
34
+ assert expected == Ohm::Types::Hash[{ :a => "b", :c => "d" }].to_s
35
+ end
36
+
37
+ test "still able to get top level methods" do
38
+ assert Post.new.hash == {}
39
+ assert Hash == Post.new.top_level_hash
40
+ end
41
+
42
+ test "handles nil case correctly" do
43
+ post = Post.create(:address => nil)
44
+ assert post.address == {}
45
+
46
+ post = Post[post.id]
47
+ assert post.address == {}
48
+ end
49
+
50
+ test "handles empty string case correctly" do
51
+ post = Post.create(:address => "")
52
+ assert post.address == {}
53
+
54
+ post = Post[post.id]
55
+ assert post.address == {}
56
+ end
57
+
58
+ test "handles populated hashes" do
59
+ address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
60
+ post = Post.create(:address => address)
61
+ assert address == post.address
62
+
63
+ post = Post[post.id]
64
+ assert address == post.address
65
+ end
66
+
67
+ test "allows for hash operations" do
68
+ address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
69
+ post = Post.create(:address => address)
70
+
71
+ assert ["address1", "city", "country"] == post.address.keys
72
+ assert ["#123", "Singapore", "SG"] == post.address.values
73
+
74
+ post = Post[post.id]
75
+ assert ["address1", "city", "country"] == post.address.keys
76
+ assert ["#123", "Singapore", "SG"] == post.address.values
77
+ end
78
+
79
+ test "handles mutation" do
80
+ address = { "address1" => "#123", "city" => "Singapore", "country" => "SG"}
81
+ post = Post.create(:address => address)
82
+
83
+ post.address["address1"] = "#456"
84
+ post.save
85
+
86
+ assert ["address1", "city", "country"] == post.address.keys
87
+ assert ["#456", "Singapore", "SG"] == post.address.values
88
+
89
+ post = Post[post.id]
90
+ assert ["address1", "city", "country"] == post.address.keys
91
+ assert ["#456", "Singapore", "SG"] == post.address.values
92
+ end
93
+
94
+ Address = Class.new(Struct.new(:city, :country))
95
+
96
+ test "raises when trying to assign a non-hash" do
97
+ assert_raise TypeError do
98
+ Post.new(:address => [])
99
+ end
100
+
101
+ assert_raise TypeError do
102
+ Post.new(:address => Address.new)
103
+ end
104
+ end
105
+
106
+ test "inspecting" do
107
+ post = Post.create(:address => { "address1" => "#456",
108
+ "city" => "Singapore",
109
+ "country" => "SG" })
110
+
111
+ expected = %q{{"address1":"#456","city":"Singapore","country":"SG"}}
112
+ assert expected == post.address.inspect
113
+
114
+ post.address = 'FooBar'
115
+ assert %{"\\\"FooBar\\\""} == post.address.inspect
116
+ end
117
+