ohm-contrib 0.0.31 → 0.0.33

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