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.
- data/LICENSE +2 -1
- data/README.markdown +2 -1
- data/Rakefile +4 -53
- data/lib/ohm/contrib.rb +2 -2
- data/lib/ohm/contrib/boundaries.rb +1 -0
- data/lib/ohm/contrib/callbacks.rb +5 -4
- data/lib/ohm/contrib/date_validations.rb +2 -1
- data/lib/ohm/contrib/extra_validations.rb +1 -0
- data/lib/ohm/contrib/length_validations.rb +1 -0
- data/lib/ohm/contrib/locking.rb +2 -1
- data/lib/ohm/contrib/lunar_macros.rb +5 -4
- data/lib/ohm/contrib/number_validations.rb +1 -0
- data/lib/ohm/contrib/slug.rb +1 -0
- data/lib/ohm/contrib/timestamping.rb +1 -0
- data/lib/ohm/contrib/typecast.rb +1 -0
- data/lib/ohm/contrib/web_validations.rb +2 -1
- data/test/autoload_test.rb +19 -0
- data/test/boundaries_test.rb +45 -0
- data/test/callbacks_lint.rb +105 -0
- data/test/date_validations_test.rb +29 -0
- data/test/helper.rb +19 -10
- data/test/instance_callbacks_test.rb +45 -0
- data/test/length_validations_test.rb +31 -0
- data/test/lunar_macros_test.rb +146 -0
- data/test/macro_callbacks_test.rb +57 -0
- data/test/membership_validation_test.rb +31 -0
- data/test/number_validations_test.rb +37 -0
- data/test/slug_test.rb +30 -0
- data/test/timestamping_test.rb +32 -0
- data/test/typecast_array_test.rb +154 -0
- data/test/typecast_boolean_test.rb +43 -0
- data/test/typecast_date_test.rb +77 -0
- data/test/typecast_decimal_test.rb +77 -0
- data/test/typecast_float_test.rb +52 -0
- data/test/typecast_hash_test.rb +117 -0
- data/test/typecast_integer_test.rb +66 -0
- data/test/typecast_string_test.rb +38 -0
- data/test/typecast_time_test.rb +67 -0
- data/test/typecast_timezone_test.rb +37 -0
- data/test/web_validations_test.rb +79 -0
- metadata +47 -56
- data/.document +0 -5
- data/.gitignore +0 -25
- data/VERSION +0 -1
- data/lib/ohm/contrib/to_hash.rb +0 -39
- data/ohm-contrib.gemspec +0 -103
- data/test/test_ohm_boundaries.rb +0 -74
- data/test/test_ohm_contrib.rb +0 -70
- data/test/test_ohm_contrib_callbacks.rb +0 -375
- data/test/test_ohm_date_validations.rb +0 -30
- data/test/test_ohm_extra_validations.rb +0 -32
- data/test/test_ohm_length_validations.rb +0 -32
- data/test/test_ohm_lunar_macros.rb +0 -165
- data/test/test_ohm_number_validations.rb +0 -59
- data/test/test_ohm_slug.rb +0 -29
- data/test/test_ohm_timestamping.rb +0 -64
- data/test/test_ohm_to_hash.rb +0 -67
- data/test/test_ohm_typecast.rb +0 -707
- data/test/test_ohm_web_validations.rb +0 -114
data/test/helper.rb
CHANGED
@@ -1,16 +1,25 @@
|
|
1
|
-
require '
|
2
|
-
require 'test/unit'
|
3
|
-
require 'contest'
|
1
|
+
require 'cutest'
|
4
2
|
require 'redis'
|
5
3
|
require 'ohm'
|
6
|
-
require '
|
7
|
-
require '
|
4
|
+
require 'ohm/contrib'
|
5
|
+
require 'override'
|
8
6
|
|
9
|
-
Ohm.connect :host => "localhost", :port =>
|
7
|
+
Ohm.connect :host => "localhost", :port => 6379, :db => 1
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
NOW = Time.utc(2010, 5, 12)
|
10
|
+
|
11
|
+
include Override
|
14
12
|
|
15
|
-
|
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
|
+
|