ohm-contrib 0.1.2 → 1.0.rc0

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 (52) hide show
  1. data/lib/ohm/{contrib/callbacks.rb → callbacks.rb} +20 -65
  2. data/lib/ohm/contrib.rb +9 -17
  3. data/lib/ohm/datatypes.rb +38 -0
  4. data/lib/ohm/{contrib/locking.rb → locking.rb} +1 -2
  5. data/lib/ohm/plugin.rb +54 -0
  6. data/lib/ohm/{contrib/scope.rb → scope.rb} +7 -6
  7. data/lib/ohm/{contrib/slug.rb → slug.rb} +11 -6
  8. data/lib/ohm/{contrib/soft_delete.rb → softdelete.rb} +23 -19
  9. data/lib/ohm/timestamping.rb +41 -0
  10. data/ohm-contrib.gemspec +30 -0
  11. data/rakefile +6 -0
  12. data/test/{instance_callbacks_test.rb → instance_callbacks.rb} +2 -6
  13. data/test/{macro_callbacks_test.rb → macro_callbacks.rb} +1 -9
  14. data/test/plugin.rb +212 -0
  15. data/test/{scope_test.rb → scope.rb} +2 -3
  16. data/test/slug.rb +24 -0
  17. data/test/{soft_delete_test.rb → soft_delete.rb} +13 -3
  18. data/test/{timestamping_test.rb → timestamping.rb} +5 -6
  19. metadata +33 -70
  20. data/Rakefile +0 -8
  21. data/lib/ohm/contrib/active_model_extension.rb +0 -87
  22. data/lib/ohm/contrib/boundaries.rb +0 -41
  23. data/lib/ohm/contrib/date_validations.rb +0 -23
  24. data/lib/ohm/contrib/extra_validations.rb +0 -48
  25. data/lib/ohm/contrib/fulltext_searching.rb +0 -80
  26. data/lib/ohm/contrib/length_validations.rb +0 -32
  27. data/lib/ohm/contrib/number_validations.rb +0 -14
  28. data/lib/ohm/contrib/timestamping.rb +0 -38
  29. data/lib/ohm/contrib/typecast.rb +0 -350
  30. data/lib/ohm/contrib/web_validations.rb +0 -52
  31. data/test/activemodel_test.rb +0 -27
  32. data/test/boundaries_test.rb +0 -45
  33. data/test/callbacks_lint.rb +0 -141
  34. data/test/date_validations_test.rb +0 -29
  35. data/test/fixtures/ascii8bit.txt +0 -1
  36. data/test/fulltext_searching_test.rb +0 -63
  37. data/test/length_validations_test.rb +0 -31
  38. data/test/membership_validation_test.rb +0 -31
  39. data/test/number_validations_test.rb +0 -37
  40. data/test/slug_test.rb +0 -30
  41. data/test/typecast_array_test.rb +0 -146
  42. data/test/typecast_boolean_test.rb +0 -43
  43. data/test/typecast_date_test.rb +0 -82
  44. data/test/typecast_decimal_test.rb +0 -82
  45. data/test/typecast_existing_attribute_test.rb +0 -22
  46. data/test/typecast_float_test.rb +0 -57
  47. data/test/typecast_hash_test.rb +0 -120
  48. data/test/typecast_integer_test.rb +0 -71
  49. data/test/typecast_string_test.rb +0 -43
  50. data/test/typecast_time_test.rb +0 -72
  51. data/test/typecast_timezone_test.rb +0 -37
  52. data/test/web_validations_test.rb +0 -79
@@ -1,141 +0,0 @@
1
- test "save on invalid" do
2
- post = Post.new
3
- post.save
4
-
5
- assert post.did?(:do_before_validate)
6
- assert post.did?(:do_after_validate)
7
-
8
- assert ! post.did?(:do_before_create)
9
- assert ! post.did?(:do_after_create)
10
- assert ! post.did?(:do_before_save)
11
- assert ! post.did?(:do_after_save)
12
- assert ! post.did?(:do_before_update)
13
- assert ! post.did?(:do_after_update)
14
- end
15
-
16
- test "saving a valid model" do
17
- post = Post.new(:body => "The Body")
18
- post.save
19
-
20
- assert post.did?(:do_before_validate)
21
- assert post.did?(:do_after_validate)
22
- assert post.did?(:do_before_create)
23
- assert post.did?(:do_after_create)
24
- assert post.did?(:do_before_save)
25
- assert post.did?(:do_after_save)
26
- assert ! post.did?(:do_before_update)
27
- assert ! post.did?(:do_after_update)
28
- end
29
-
30
- test "ensure create / save callbacks are only called once" do
31
- post = Post.new(:body => "The Body")
32
- post.save
33
-
34
- assert 1 == post.count(:do_before_create)
35
- assert 1 == post.count(:do_after_create)
36
- assert 1 == post.count(:do_before_save)
37
- assert 1 == post.count(:do_after_create)
38
- end
39
-
40
- test "Post::create on a valid model invokes all callbacks (except update)" do
41
- post = Post.create(:body => "The Body")
42
-
43
- assert post.did?(:do_before_validate)
44
- assert post.did?(:do_after_validate)
45
- assert post.did?(:do_before_create)
46
- assert post.did?(:do_after_create)
47
- assert post.did?(:do_before_save)
48
- assert post.did?(:do_after_save)
49
- assert ! post.did?(:do_before_update)
50
- assert ! post.did?(:do_after_update)
51
- end
52
-
53
- test "ensure Post::create only invokes save / create once" do
54
- post = Post.create(:body => "The Body")
55
-
56
- assert 1 == post.count(:do_before_create)
57
- assert 1 == post.count(:do_after_create)
58
- assert 1 == post.count(:do_before_save)
59
- assert 1 == post.count(:do_after_create)
60
- end
61
-
62
- test "on successful save of existing record" do
63
- post = Post.create(:body => "The Body")
64
- post = Post[post.id]
65
- post.save
66
-
67
- assert ! post.did?(:do_before_create)
68
- assert ! post.did?(:do_after_create)
69
-
70
- assert post.did?(:do_before_validate)
71
- assert post.did?(:do_after_validate)
72
- assert post.did?(:do_before_save)
73
- assert post.did?(:do_after_save)
74
- assert post.did?(:do_before_update)
75
- assert post.did?(:do_after_update)
76
-
77
- assert 1 == post.count(:do_before_save)
78
- assert 1 == post.count(:do_after_save)
79
- assert 1 == post.count(:do_before_update)
80
- assert 1 == post.count(:do_after_update)
81
- end
82
-
83
- test "on successful save of existing record (using #update)" do
84
- post = Post.create(:body => "The Body")
85
- post = Post[post.id]
86
- post.update(:body => "New Body")
87
-
88
- assert ! post.did?(:do_before_create)
89
- assert ! post.did?(:do_after_create)
90
-
91
- assert post.did?(:do_before_validate)
92
- assert post.did?(:do_after_validate)
93
- assert post.did?(:do_before_save)
94
- assert post.did?(:do_after_save)
95
- assert post.did?(:do_before_update)
96
- assert post.did?(:do_after_update)
97
-
98
- assert 1 == post.count(:do_before_save)
99
- assert 1 == post.count(:do_after_save)
100
- assert 1 == post.count(:do_before_update)
101
- assert 1 == post.count(:do_after_update)
102
- end
103
-
104
- test "on failed save of existing record" do
105
- post = Post.create(:body => "The Body")
106
- post = Post[post.id]
107
-
108
- post.body = nil
109
- post.save
110
-
111
- assert post.did?(:do_before_validate)
112
- assert post.did?(:do_after_validate)
113
-
114
- assert ! post.did?(:do_before_create)
115
- assert ! post.did?(:do_after_create)
116
-
117
- assert ! post.did?(:do_before_save)
118
- assert ! post.did?(:do_after_save)
119
-
120
- assert ! post.did?(:do_before_update)
121
- assert ! post.did?(:do_after_update)
122
- end
123
-
124
- test "on delete" do
125
- post = Post.create(:body => "The Body")
126
- post = Post[post.id]
127
- post.delete
128
-
129
- assert 1 == post.count(:do_before_delete)
130
- assert 1 == post.count(:do_after_delete)
131
-
132
- assert ! post.did?(:do_before_validate)
133
- assert ! post.did?(:do_after_validate)
134
- assert ! post.did?(:do_before_create)
135
- assert ! post.did?(:do_after_create)
136
- assert ! post.did?(:do_before_save)
137
- assert ! post.did?(:do_after_save)
138
- assert ! post.did?(:do_before_update)
139
- assert ! post.did?(:do_after_update)
140
- end
141
-
@@ -1,29 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- class Person < Ohm::Model
6
- include Ohm::DateValidations
7
-
8
- attribute :birthday
9
-
10
- def validate
11
- assert_date :birthday
12
- end
13
- end
14
-
15
- test "accepts all canonical dates" do
16
- assert Person.new(:birthday => "2010-05-05").valid?
17
- assert Person.new(:birthday => "2010-5-5").valid?
18
- assert Person.new(:birthday => "2010-05-5").valid?
19
- assert Person.new(:birthday => "2010-5-05").valid?
20
- end
21
-
22
- test "also catches invalid dates" do
23
- assert ! Person.new(:birthday => "2010-02-29").valid?
24
- end
25
-
26
- test "invalid when empty" do
27
- assert ! Person.new(:birthday => "").valid?
28
- end
29
-
@@ -1 +0,0 @@
1
- café
@@ -1,63 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- class Video < Ohm::Model
6
- include Ohm::FulltextSearching
7
-
8
- attribute :title
9
- attribute :description
10
-
11
- fulltext :title
12
- fulltext :description
13
- end
14
-
15
- test "finding basic words using metaphones" do
16
- v = Video.create(:title => "The quick brown fox jumps over the lazy dog")
17
-
18
- assert Video.find(:fulltext_title => "KK").include?(v)
19
- assert Video.find(:fulltext_title => "PRN").include?(v)
20
- assert Video.find(:fulltext_title => "FKS").include?(v)
21
- assert Video.find(:fulltext_title => "JMPS").include?(v)
22
- assert Video.find(:fulltext_title => "AMPS").include?(v)
23
- assert Video.find(:fulltext_title => ["JMPS", "AMPS"]).include?(v)
24
- assert Video.find(:fulltext_title => "LS").include?(v)
25
- assert Video.find(:fulltext_title => "TK").include?(v)
26
- end
27
-
28
- test "finding using the actual words" do
29
- v = Video.create(:title => "The quick brown fox jumps over the lazy dog")
30
-
31
- assert Video.search(:title => "quick").include?(v)
32
- assert Video.search(:title => "brown").include?(v)
33
- assert Video.search(:title => "fox").include?(v)
34
- assert Video.search(:title => "jumps").include?(v)
35
- assert Video.search(:title => "lazy").include?(v)
36
- assert Video.search(:title => "dog").include?(v)
37
- end
38
-
39
- test "finding using slightly mispelled words" do
40
- v = Video.create(:title => "The quick brown fox jumps over the lazy dog")
41
-
42
- assert Video.search(:title => "quik").include?(v)
43
- assert Video.search(:title => "brwn").include?(v)
44
- assert Video.search(:title => "fx").include?(v)
45
- assert Video.search(:title => "fax").include?(v)
46
- assert Video.search(:title => "jumps").include?(v)
47
- assert Video.search(:title => "lazi").include?(v)
48
- assert Video.search(:title => "dag").include?(v)
49
- end
50
-
51
- test "stopword stripping" do
52
- # This is the actual code that strips out stopwords.
53
-
54
- assert_equal [], Video.double_metaphone("about")
55
-
56
- # Here we just verify that actually on a long string level,
57
- # stop words are in fact stripped.
58
- assert Video.metaphones(Video::STOPWORDS.join(" ")).empty?
59
-
60
- # Finally we need to make sure that finding stop words
61
- # should not even proceed.
62
- assert Video.hash_to_metaphones(:title => "about").empty?
63
- end
@@ -1,31 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- class Person < Ohm::Model
6
- include Ohm::LengthValidations
7
-
8
- attribute :name
9
-
10
- def validate
11
- assert_min_length :name, 5
12
- assert_max_length :name, 10
13
- end
14
- end
15
-
16
- test "valid length name" do
17
- assert Person.new(:name => "bob smith").valid?
18
- end
19
-
20
- test "also catches short strings" do
21
- assert ! Person.new(:name => "bob").valid?
22
- end
23
-
24
- test "also catches long strings" do
25
- assert ! Person.new(:name => "robert smithson").valid?
26
- end
27
-
28
- test "invalid when empty" do
29
- assert ! Person.new(:name => "").valid?
30
- end
31
-
@@ -1,31 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- class Order < Ohm::Model
6
- include Ohm::ExtraValidations
7
-
8
- attribute :state
9
-
10
- def validate
11
- assert_member :state, %w(pending authorized declined)
12
- end
13
- end
14
-
15
- test "validates for all members" do
16
- order = Order.new(:state => 'pending')
17
- assert order.valid?
18
-
19
- order = Order.new(:state => 'authorized')
20
- assert order.valid?
21
-
22
- order = Order.new(:state => 'declined')
23
- assert order.valid?
24
- end
25
-
26
- test "fails on a non-member" do
27
- order = Order.new(:state => 'foobar')
28
- assert ! order.valid?
29
- assert [[:state, :not_member]] == order.errors
30
- end
31
-
@@ -1,37 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- class Product < Ohm::Model
6
- include Ohm::NumberValidations
7
-
8
- attribute :price
9
- attribute :optional_price
10
-
11
- def validate
12
- assert_decimal :price
13
- assert_decimal :optional_price unless optional_price.to_s.empty?
14
- end
15
- end
16
-
17
- test "has error when empty" do
18
- product = Product.new(:price => nil)
19
- product.valid?
20
-
21
- assert [[:price, :not_decimal]] == product.errors
22
- end
23
-
24
- test "validation scenarios" do
25
- assert Product.new(:price => 0.10).valid?
26
- assert Product.new(:price => 1).valid?
27
-
28
- p = Product.new(:price => '1.')
29
- assert ! p.valid?
30
- assert [[:price, :not_decimal]] == p.errors
31
- end
32
-
33
- test "allows empty values through basic ruby conditions" do
34
- assert Product.new(:price => 10.1, :optional_price => nil).valid?
35
- assert Product.new(:price => 10.1, :optional_price => '').valid?
36
- end
37
-
data/test/slug_test.rb DELETED
@@ -1,30 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require File.expand_path("./helper", File.dirname(__FILE__))
4
-
5
- module Finder
6
- def [](id)
7
- new(id)
8
- end
9
- end
10
-
11
- class BaseWithoutToParam < Struct.new(:id)
12
- extend Finder
13
-
14
- include Ohm::Slug
15
-
16
- def to_s
17
- "A very Unique and Interesting String?'"
18
- end
19
- end
20
-
21
- test "to_param" do
22
- obj = BaseWithoutToParam.new(1)
23
-
24
- assert '1-a-very-unique-and-interesting-string' == obj.to_param
25
- end
26
-
27
- test "finding" do
28
- assert 1 == BaseWithoutToParam['1-a-very-unique'].id
29
- end
30
-
@@ -1,146 +0,0 @@
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 "type is array" do
143
- post = Post.create(:addresses => ["address1"])
144
-
145
- assert post.addresses.type == Array
146
- end
@@ -1,43 +0,0 @@
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
-
@@ -1,82 +0,0 @@
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
-
78
- test "type is Date" do
79
- post = Post.create(:created_on => Date.new(2010, 5, 5))
80
- assert Date == post.created_on.type
81
- end
82
-