ohm-contrib 0.1.2 → 1.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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
-