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
data/test/helper.rb CHANGED
@@ -1,16 +1,25 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'contest'
1
+ require 'cutest'
4
2
  require 'redis'
5
3
  require 'ohm'
6
- require 'timecop'
7
- require 'mocha'
4
+ require 'ohm/contrib'
5
+ require 'override'
8
6
 
9
- Ohm.connect :host => "localhost", :port => "6379"
7
+ Ohm.connect :host => "localhost", :port => 6379, :db => 1
10
8
 
11
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
- $LOAD_PATH.unshift(File.dirname(__FILE__))
13
- require 'ohm/contrib'
9
+ NOW = Time.utc(2010, 5, 12)
10
+
11
+ include Override
14
12
 
15
- class Test::Unit::TestCase
13
+ prepare {
14
+ Ohm.flush
15
+ override(Time, :now => NOW)
16
+ }
17
+
18
+ def assert_nothing_raised(*exceptions)
19
+ begin
20
+ yield
21
+ rescue *exceptions
22
+ flunk(caller[1])
23
+ end
16
24
  end
25
+
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Callbacks
7
+
8
+ attribute :body
9
+
10
+ def validate
11
+ super
12
+
13
+ assert_present :body
14
+ end
15
+
16
+ def did?(action)
17
+ instance_variable_get("@#{ action }")
18
+ end
19
+
20
+ def count(action)
21
+ instance_variable_get("@#{ action }")
22
+ end
23
+
24
+ protected
25
+ def before_validate() incr(:do_before_validate) end
26
+ def after_validate() incr(:do_after_validate) end
27
+ def before_create() incr(:do_before_create) end
28
+ def after_create() incr(:do_after_create) end
29
+ def before_save() incr(:do_before_save) end
30
+ def after_save() incr(:do_after_save) end
31
+ def before_delete() incr(:do_before_delete) end
32
+ def after_delete() incr(:do_after_delete) end
33
+
34
+
35
+ def incr(action)
36
+ val = instance_variable_get("@#{ action }")
37
+ val ||= 0
38
+ val += 1
39
+
40
+ instance_variable_set("@#{ action }", val)
41
+ end
42
+ end
43
+
44
+ load File.expand_path('./callbacks_lint.rb', File.dirname(__FILE__))
45
+
@@ -0,0 +1,31 @@
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
+
@@ -0,0 +1,146 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::LunarMacros
7
+ end
8
+
9
+ test "fuzzy / text / number / sortable" do
10
+ Post.fuzzy :name
11
+ assert [:name] == Post.fuzzy
12
+
13
+ Post.text :name
14
+ assert [:name] == Post.text
15
+
16
+ Post.number :name
17
+ assert [:name] == Post.number
18
+
19
+ Post.sortable :name
20
+ assert [:name] == Post.sortable
21
+ end
22
+
23
+ test "fuzzy / text / number / sortable done twice" do
24
+ Post.fuzzy :name
25
+ Post.fuzzy :name
26
+ assert [:name] == Post.fuzzy
27
+
28
+ Post.text :name
29
+ Post.text :name
30
+ assert [:name] == Post.text
31
+
32
+ Post.number :name
33
+ Post.number :name
34
+ assert [:name] == Post.number
35
+
36
+ Post.sortable :name
37
+ Post.sortable :name
38
+ assert [:name] == Post.sortable
39
+ end
40
+
41
+ class Document < Ohm::Model
42
+ include Ohm::LunarMacros
43
+
44
+ fuzzy :filename
45
+ text :content
46
+ number :author_id
47
+ sortable :views
48
+
49
+ attribute :filename
50
+ attribute :content
51
+ attribute :author_id
52
+ attribute :views
53
+ end
54
+
55
+ test "fuzzy indexing" do
56
+ doc = Document.create(:filename => "amazing.mp3")
57
+
58
+ strs = %w{a am ama amaz amazi amazin amazing amazing. amazing.m
59
+ amazing.mp amazing.mp3}
60
+
61
+ strs.each do |str|
62
+ r = Lunar.search(Document, :fuzzy => { :filename => str })
63
+ assert r.include?(doc)
64
+ end
65
+
66
+ doc.update(:filename => "crazy.mp3")
67
+
68
+ strs = %w{c cr cra craz crazy crazy. crazy.m crazy.mp crazy.mp3}
69
+
70
+ strs.each do |str|
71
+ r = Lunar.search(Document, :fuzzy => { :filename => str })
72
+ assert r.include?(doc)
73
+ end
74
+ end
75
+
76
+ test "text indexing" do
77
+ doc = Document.create(:content => "The quick brown fox")
78
+
79
+ queries = ['quick', 'brown', 'fox', 'quick brown' 'quick fox', 'fox brown',
80
+ 'the quick brown fox']
81
+
82
+ queries.each do |q|
83
+ r = Lunar.search(Document, :q => q)
84
+ assert r.include?(doc)
85
+ end
86
+
87
+ doc.update(:content => "lazy dog jumps over")
88
+
89
+ queries = ['lazy', 'dog', 'jumps', 'over', 'lazy dog', 'jumps over']
90
+
91
+ queries.each do |q|
92
+ r = Lunar.search(Document, :q => q)
93
+ assert r.include?(doc)
94
+ end
95
+ end
96
+
97
+ test "number indexing" do
98
+ doc = Document.create(:author_id => 99)
99
+
100
+ [99..100, 98..99, 98..100].each do |range|
101
+ r = Lunar.search(Document, :author_id => range)
102
+ assert r.include?(doc)
103
+ end
104
+
105
+ [97..98, 100..101].each do |range|
106
+ r = Lunar.search(Document, :author_id => range)
107
+ assert ! r.include?(doc)
108
+ end
109
+
110
+ doc.update(:author_id => 49)
111
+
112
+ [49..50, 48..49, 48..50].each do |range|
113
+ r = Lunar.search(Document, :author_id => range)
114
+ assert r.include?(doc)
115
+ end
116
+
117
+ [47..48, 50..51].each do |range|
118
+ r = Lunar.search(Document, :author_id => range)
119
+ assert ! r.include?(doc)
120
+ end
121
+ end
122
+
123
+ test "sortable indexing" do
124
+ osx = Document.create(:content => "apple mac osx", :views => 500)
125
+ iphone = Document.create(:content => "apple iphone", :views => 10_000)
126
+
127
+ assert [iphone, osx] == Lunar.search(Document, :q => "apple").sort_by(:views, :order => "DESC")
128
+ assert [osx, iphone] == Lunar.search(Document, :q => "apple").sort_by(:views, :order => "ASC")
129
+
130
+ osx.update(:content => "ios mac osx", :views => 1000)
131
+ iphone.update(:content => "ios iphone", :views => 500)
132
+
133
+ assert [osx, iphone] == Lunar.search(Document, :q => "ios").sort_by(:views, :order => "DESC")
134
+ assert [iphone, osx] == Lunar.search(Document, :q => "ios").sort_by(:views, :order => "ASC")
135
+ end
136
+
137
+ test "on delete" do
138
+ doc = Document.create(:filename => "amazing.mp3", :content => "apple mac osx",
139
+ :author_id => 99, :views => 500)
140
+
141
+ doc.delete
142
+
143
+ assert Lunar.search(Document, :q => "apple").size.zero?
144
+ assert Lunar.search(Document, :fuzzy => { :filename => "amazing" }).size.zero?
145
+ end
146
+
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Post < Ohm::Model
6
+ include Ohm::Callbacks
7
+
8
+ attribute :body
9
+
10
+ before :validate, :do_before_validate
11
+ after :validate, :do_after_validate
12
+
13
+ before :create, :do_before_create
14
+ after :create, :do_after_create
15
+
16
+ before :save, :do_before_save
17
+ after :save, :do_after_save
18
+
19
+ before :delete, :do_before_delete
20
+ after :delete, :do_after_delete
21
+
22
+ def validate
23
+ super
24
+
25
+ assert_present :body
26
+ end
27
+
28
+ def did?(action)
29
+ instance_variable_get("@#{ action }")
30
+ end
31
+
32
+ def count(action)
33
+ instance_variable_get("@#{ action }")
34
+ end
35
+
36
+ protected
37
+ def do_before_validate() incr(:do_before_validate) end
38
+ def do_after_validate() incr(:do_after_validate) end
39
+ def do_before_create() incr(:do_before_create) end
40
+ def do_after_create() incr(:do_after_create) end
41
+ def do_before_save() incr(:do_before_save) end
42
+ def do_after_save() incr(:do_after_save) end
43
+ def do_before_delete() incr(:do_before_delete) end
44
+ def do_after_delete() incr(:do_after_delete) end
45
+
46
+
47
+ def incr(action)
48
+ val = instance_variable_get("@#{ action }")
49
+ val ||= 0
50
+ val += 1
51
+
52
+ instance_variable_set("@#{ action }", val)
53
+ end
54
+ end
55
+
56
+ load File.expand_path('./callbacks_lint.rb', File.dirname(__FILE__))
57
+
@@ -0,0 +1,31 @@
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
+
@@ -0,0 +1,37 @@
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 ADDED
@@ -0,0 +1,30 @@
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
+
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("./helper", File.dirname(__FILE__))
4
+
5
+ class Person < Ohm::Model
6
+ include Ohm::Timestamping
7
+ end
8
+
9
+ test "a new? record" do
10
+ assert nil == Person.new.created_at
11
+ assert nil == Person.new.updated_at
12
+ end
13
+
14
+ test "on create" do
15
+ person = Person.create
16
+ person = Person[person.id]
17
+
18
+ assert NOW.to_s == person.created_at
19
+ assert NOW.to_s == person.updated_at
20
+ end
21
+
22
+ test "on update" do
23
+ person = Person.create
24
+
25
+ override(Time, :now => Time.utc(2010, 5, 13))
26
+ person.save
27
+ person = Person[person.id]
28
+
29
+ assert NOW.to_s == person.created_at
30
+ assert Time.utc(2010, 5, 13).to_s == person.updated_at
31
+ end
32
+