ohm-contrib 0.0.27 → 0.0.28

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -15,6 +15,7 @@ begin
15
15
  gem.add_development_dependency "ohm", ">= 0"
16
16
  gem.add_development_dependency "timecop", ">= 0"
17
17
  gem.add_development_dependency "mocha", ">= 0"
18
+ gem.add_development_dependency "lunar", ">= 0"
18
19
  end
19
20
  Jeweler::GemcutterTasks.new
20
21
  rescue LoadError
@@ -53,4 +54,4 @@ Rake::RDocTask.new do |rdoc|
53
54
  rdoc.title = "ohm-contrib #{version}"
54
55
  rdoc.rdoc_files.include('README*')
55
56
  rdoc.rdoc_files.include('lib/**/*.rb')
56
- end
57
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.27
1
+ 0.0.28
@@ -1,6 +1,20 @@
1
1
  module Ohm
2
2
  # Minimalistic callback support for Ohm::Model.
3
3
  #
4
+ # You can implement callbacks by overriding any of the following
5
+ # methods:
6
+ #
7
+ # - before_validate
8
+ # - after_validate
9
+ # - before_create
10
+ # - after_create
11
+ # - before_save
12
+ # - after_save
13
+ # - before_delete
14
+ # - after_delete
15
+ #
16
+ # If you prefer to do a class level declaration that is also possible.
17
+ #
4
18
  # @example
5
19
  #
6
20
  # class Post < Ohm::Model
@@ -35,7 +49,7 @@ module Ohm
35
49
  # # do something with the ids
36
50
  # end
37
51
  # end
38
- #
52
+
39
53
  module Callbacks
40
54
  def self.included(base)
41
55
  base.extend Macros
@@ -171,16 +185,29 @@ module Ohm
171
185
 
172
186
  def delete
173
187
  execute_callback(:before, :delete)
188
+
174
189
  super.tap do |is_deleted|
175
190
  execute_callback(:after, :delete) if is_deleted
176
191
  end
177
192
  end
193
+
194
+ protected
195
+ def before_validate() end
196
+ def after_validate() end
197
+ def before_save() end
198
+ def after_save() end
199
+ def before_create() end
200
+ def after_create() end
201
+ def before_delete() end
202
+ def after_delete() end
178
203
 
179
204
  private
180
205
  def execute_callback(position, method)
181
206
  self.class.callbacks[position][method].each do |callback|
182
207
  __send__(callback)
183
208
  end
209
+
210
+ __send__("#{ position }_#{ method }")
184
211
  end
185
212
  end
186
213
  end
@@ -2,11 +2,11 @@ require 'date'
2
2
 
3
3
  module Ohm
4
4
  module DateValidations
5
- DATE = /\A([0-9]{4})-([01]?[0-9])-([0123]?[0-9])\z/
5
+ DATE_REGEX = /\A([0-9]{4})-([01]?[0-9])-([0123]?[0-9])\z/
6
6
 
7
7
  def assert_date(att, error = [att, :not_date])
8
- if assert_format att, DATE, error
9
- m = send(att).to_s.match(DATE)
8
+ if assert_format att, DATE_REGEX, error
9
+ m = send(att).to_s.match(DATE_REGEX)
10
10
  assert is_date_parseable?(m[1], m[2], m[3]), error
11
11
  end
12
12
  end
@@ -0,0 +1,53 @@
1
+ begin
2
+ require 'lunar'
3
+ rescue LoadError
4
+ raise "You have to install Lunar in order to use Ohm::LunarMacros."
5
+ end
6
+
7
+ module Ohm
8
+ module LunarMacros
9
+ def self.included(base)
10
+ base.send :include, Ohm::Callbacks
11
+ base.after :save, :update_lunar_index
12
+ base.after :delete, :delete_lunar_index
13
+
14
+ base.extend ClassMethods
15
+ end
16
+
17
+ module ClassMethods
18
+ def fuzzy(*atts) lunar_fields(:fuzzy, *atts) end
19
+ def text(*atts) lunar_fields(:text, *atts) end
20
+ def number(*atts) lunar_fields(:number, *atts) end
21
+ def sortable(*atts) lunar_fields(:sortable, *atts) end
22
+
23
+ def lunar_fields(type, *atts)
24
+ @lunar_fields ||= Hash.new { |h, k| h[k] = [] }
25
+
26
+ atts.each { |att|
27
+ @lunar_fields[type] << att unless @lunar_fields[type].include?(att)
28
+ }
29
+
30
+ @lunar_fields[type]
31
+ end
32
+ end
33
+
34
+ def update_lunar_index
35
+ Lunar.index self.class do |i|
36
+ i.id id
37
+
38
+ [:fuzzy, :text, :number, :sortable].each do |type|
39
+ self.class.lunar_fields(type).each do |field|
40
+ value = send(field)
41
+
42
+ i.send type, field, value unless value.to_s.empty?
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ protected
49
+ def delete_lunar_index
50
+ Lunar.delete self.class, id
51
+ end
52
+ end
53
+ end
@@ -1,12 +1,13 @@
1
1
  module Ohm
2
2
  # This module will include all numeric validation needs.
3
- # As of VERSION 0.0.15, Ohm::NumberValidations#assert_decimal
3
+ # As of VERSION 0.0.27, Ohm::NumberValidations#assert_decimal
4
4
  # is the only method provided.
5
5
  module NumberValidations
6
+ DECIMAL_REGEX = /^(\d+)?(\.\d+)?$/
6
7
 
7
8
  protected
8
9
  def assert_decimal(att, error = [att, :not_decimal])
9
- assert_format(att, /^(\d+)?(\.\d+)?$/, error)
10
+ assert_format att, DECIMAL_REGEX, error
10
11
  end
11
12
  end
12
- end
13
+ end
@@ -0,0 +1,22 @@
1
+ module Ohm
2
+ module Slug
3
+ def self.included(base)
4
+ base.extend FinderOverride
5
+ end
6
+
7
+ module FinderOverride
8
+ def [](id)
9
+ super(id.to_i)
10
+ end
11
+ end
12
+
13
+ def slug(str = to_s)
14
+ str.gsub("'", "").gsub(/\p{^Alnum}/u, " ").strip.gsub(/\s+/, "-").downcase
15
+ end
16
+ module_function :slug
17
+
18
+ def to_param
19
+ "#{ id }-#{ slug }"
20
+ end
21
+ end
22
+ end
@@ -25,6 +25,8 @@ module Ohm
25
25
  #
26
26
  # Post.create(:body => "Body").to_hash == { :id => 1, :body => "Body" }
27
27
  # # => true
28
+ #
29
+ # @todo use super when Ohm has finally release their #to_hash impl.
28
30
  module ToHash
29
31
  def to_hash
30
32
  atts = attributes + counters
@@ -34,4 +36,4 @@ module Ohm
34
36
  end
35
37
  alias :to_h :to_hash
36
38
  end
37
- end
39
+ end
@@ -75,7 +75,6 @@ module Ohm
75
75
  @raw.respond_to?(method)
76
76
  end
77
77
 
78
- protected
79
78
  def object
80
79
  @raw
81
80
  end
@@ -88,7 +87,6 @@ module Ohm
88
87
  class Decimal < Primitive
89
88
  delegate_to ::BigDecimal
90
89
 
91
- protected
92
90
  def object
93
91
  ::Kernel::BigDecimal(@raw)
94
92
  end
@@ -97,7 +95,6 @@ module Ohm
97
95
  class Integer < Primitive
98
96
  delegate_to ::Fixnum
99
97
 
100
- protected
101
98
  def object
102
99
  ::Kernel::Integer(@raw)
103
100
  end
@@ -106,7 +103,6 @@ module Ohm
106
103
  class Float < Primitive
107
104
  delegate_to ::Float
108
105
 
109
- protected
110
106
  def object
111
107
  ::Kernel::Float(@raw)
112
108
  end
@@ -115,7 +111,6 @@ module Ohm
115
111
  class Time < Primitive
116
112
  delegate_to ::Time
117
113
 
118
- protected
119
114
  def object
120
115
  ::Time.parse(@raw)
121
116
  end
@@ -124,7 +119,6 @@ module Ohm
124
119
  class Date < Primitive
125
120
  delegate_to ::Date
126
121
 
127
- protected
128
122
  def object
129
123
  ::Date.parse(@raw)
130
124
  end
@@ -175,7 +169,7 @@ module Ohm
175
169
  end
176
170
 
177
171
  class Hash < Serialized
178
- RAW = ::Hash
172
+ RAW = ::Hash
179
173
 
180
174
  delegate_to ::Hash
181
175
 
@@ -187,7 +181,7 @@ module Ohm
187
181
  end
188
182
 
189
183
  class Array < Serialized
190
- RAW = ::Array
184
+ RAW = ::Array
191
185
 
192
186
  delegate_to ::Array
193
187
 
data/lib/ohm/contrib.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Ohm
2
2
  module Contrib
3
- VERSION = '0.0.27'
3
+ VERSION = '0.0.28'
4
4
  end
5
5
 
6
6
  autoload :Boundaries, "ohm/contrib/boundaries"
@@ -13,4 +13,6 @@ module Ohm
13
13
  autoload :Typecast, "ohm/contrib/typecast"
14
14
  autoload :Locking, "ohm/contrib/locking"
15
15
  autoload :Callbacks, "ohm/contrib/callbacks"
16
+ autoload :LunarMacros, "ohm/contrib/lunar_macros"
17
+ autoload :Slug, "ohm/contrib/slug"
16
18
  end
data/ohm-contrib.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ohm-contrib}
8
- s.version = "0.0.27"
8
+ s.version = "0.0.28"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cyril David"]
12
- s.date = %q{2010-06-29}
12
+ s.date = %q{2010-07-02}
13
13
  s.description = %q{Highly decoupled drop-in functionality for Ohm models}
14
14
  s.email = %q{cyx.ucron@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -29,7 +29,9 @@ Gem::Specification.new do |s|
29
29
  "lib/ohm/contrib/date_validations.rb",
30
30
  "lib/ohm/contrib/extra_validations.rb",
31
31
  "lib/ohm/contrib/locking.rb",
32
+ "lib/ohm/contrib/lunar_macros.rb",
32
33
  "lib/ohm/contrib/number_validations.rb",
34
+ "lib/ohm/contrib/slug.rb",
33
35
  "lib/ohm/contrib/timestamping.rb",
34
36
  "lib/ohm/contrib/to_hash.rb",
35
37
  "lib/ohm/contrib/typecast.rb",
@@ -41,7 +43,9 @@ Gem::Specification.new do |s|
41
43
  "test/test_ohm_contrib_callbacks.rb",
42
44
  "test/test_ohm_date_validations.rb",
43
45
  "test/test_ohm_extra_validations.rb",
46
+ "test/test_ohm_lunar_macros.rb",
44
47
  "test/test_ohm_number_validations.rb",
48
+ "test/test_ohm_slug.rb",
45
49
  "test/test_ohm_timestamping.rb",
46
50
  "test/test_ohm_to_hash.rb",
47
51
  "test/test_ohm_typecast.rb",
@@ -50,7 +54,7 @@ Gem::Specification.new do |s|
50
54
  s.homepage = %q{http://labs.sinefunc.com/ohm-contrib}
51
55
  s.rdoc_options = ["--charset=UTF-8"]
52
56
  s.require_paths = ["lib"]
53
- s.rubygems_version = %q{1.3.7}
57
+ s.rubygems_version = %q{1.3.6}
54
58
  s.summary = %q{A collection of ohm related modules}
55
59
  s.test_files = [
56
60
  "test/helper.rb",
@@ -59,7 +63,9 @@ Gem::Specification.new do |s|
59
63
  "test/test_ohm_contrib_callbacks.rb",
60
64
  "test/test_ohm_date_validations.rb",
61
65
  "test/test_ohm_extra_validations.rb",
66
+ "test/test_ohm_lunar_macros.rb",
62
67
  "test/test_ohm_number_validations.rb",
68
+ "test/test_ohm_slug.rb",
63
69
  "test/test_ohm_timestamping.rb",
64
70
  "test/test_ohm_to_hash.rb",
65
71
  "test/test_ohm_typecast.rb",
@@ -70,18 +76,20 @@ Gem::Specification.new do |s|
70
76
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
71
77
  s.specification_version = 3
72
78
 
73
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
74
80
  s.add_development_dependency(%q<contest>, [">= 0"])
75
81
  s.add_development_dependency(%q<redis>, [">= 0"])
76
82
  s.add_development_dependency(%q<ohm>, [">= 0"])
77
83
  s.add_development_dependency(%q<timecop>, [">= 0"])
78
84
  s.add_development_dependency(%q<mocha>, [">= 0"])
85
+ s.add_development_dependency(%q<lunar>, [">= 0"])
79
86
  else
80
87
  s.add_dependency(%q<contest>, [">= 0"])
81
88
  s.add_dependency(%q<redis>, [">= 0"])
82
89
  s.add_dependency(%q<ohm>, [">= 0"])
83
90
  s.add_dependency(%q<timecop>, [">= 0"])
84
91
  s.add_dependency(%q<mocha>, [">= 0"])
92
+ s.add_dependency(%q<lunar>, [">= 0"])
85
93
  end
86
94
  else
87
95
  s.add_dependency(%q<contest>, [">= 0"])
@@ -89,6 +97,7 @@ Gem::Specification.new do |s|
89
97
  s.add_dependency(%q<ohm>, [">= 0"])
90
98
  s.add_dependency(%q<timecop>, [">= 0"])
91
99
  s.add_dependency(%q<mocha>, [">= 0"])
100
+ s.add_dependency(%q<lunar>, [">= 0"])
92
101
  end
93
102
  end
94
103
 
@@ -54,4 +54,17 @@ class TestOhmContrib < Test::Unit::TestCase
54
54
  Ohm::DateValidations
55
55
  end
56
56
  end
57
+
58
+ test "autoloading of LunarMacros" do
59
+ require 'lunar'
60
+ assert_nothing_raised NameError, LoadError do
61
+ Ohm::LunarMacros
62
+ end
63
+ end
64
+
65
+ test "autoloading of Slug" do
66
+ assert_nothing_raised NameError, LoadError do
67
+ Ohm::Slug
68
+ end
69
+ end
57
70
  end
@@ -1,193 +1,375 @@
1
1
  require "helper"
2
2
 
3
3
  class OhmContribCallbacksTest < Test::Unit::TestCase
4
- class Post < Ohm::Model
5
- include Ohm::Callbacks
4
+ describe "instance level validation callbacks" do
5
+ class InstanceTypePost < Ohm::Model
6
+ include Ohm::Callbacks
6
7
 
7
- attribute :body
8
+ attribute :body
8
9
 
9
- before :validate, :do_before_validate
10
- after :validate, :do_after_validate
10
+ def validate
11
+ super
11
12
 
12
- before :create, :do_before_create
13
- after :create, :do_after_create
13
+ assert_present :body
14
+ end
14
15
 
15
- before :save, :do_before_save
16
- after :save, :do_after_save
16
+ def did?(action)
17
+ instance_variable_get("@#{ action }")
18
+ end
17
19
 
18
- before :delete, :do_before_delete
19
- after :delete, :do_after_delete
20
+ def count(action)
21
+ instance_variable_get("@#{ action }")
22
+ end
20
23
 
21
- def validate
22
- super
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
23
33
 
24
- assert_present :body
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
25
42
  end
26
43
 
27
- def did?(action)
28
- instance_variable_get("@#{ action }")
44
+ context "on save when invalid state" do
45
+ setup do
46
+ @post = InstanceTypePost.new
47
+ @post.save
48
+ end
49
+
50
+ should "still call before / after validate" do
51
+ assert @post.did?(:do_before_validate)
52
+ assert @post.did?(:do_after_validate)
53
+ end
54
+
55
+ should "not call all other callbacks" do
56
+ assert ! @post.did?(:do_before_create)
57
+ assert ! @post.did?(:do_after_create)
58
+ assert ! @post.did?(:do_before_save)
59
+ assert ! @post.did?(:do_after_save)
60
+ end
29
61
  end
30
62
 
31
- def count(action)
32
- instance_variable_get("@#{ action }")
63
+ context "on save when valid state" do
64
+ setup do
65
+ @post = InstanceTypePost.new(:body => "The Body")
66
+ @post.save
67
+ end
68
+
69
+ should "call all callbacks" do
70
+ assert @post.did?(:do_before_validate)
71
+ assert @post.did?(:do_after_validate)
72
+ assert @post.did?(:do_before_create)
73
+ assert @post.did?(:do_after_create)
74
+ assert @post.did?(:do_before_save)
75
+ assert @post.did?(:do_after_save)
76
+ end
77
+
78
+ should "call create / save callbacks only once" do
79
+ assert_equal 1, @post.count(:do_before_create)
80
+ assert_equal 1, @post.count(:do_after_create)
81
+ assert_equal 1, @post.count(:do_before_save)
82
+ assert_equal 1, @post.count(:do_after_create)
83
+ end
33
84
  end
34
85
 
35
- protected
36
- def do_before_validate() incr(:do_before_validate) end
37
- def do_after_validate() incr(:do_after_validate) end
38
- def do_before_create() incr(:do_before_create) end
39
- def do_after_create() incr(:do_after_create) end
40
- def do_before_save() incr(:do_before_save) end
41
- def do_after_save() incr(:do_after_save) end
42
- def do_before_delete() incr(:do_before_delete) end
43
- def do_after_delete() incr(:do_after_delete) end
86
+ context "on create when valid state" do
87
+ setup do
88
+ @post = InstanceTypePost.create(:body => "The Body")
89
+ end
90
+
91
+ should "call all callbacks" do
92
+ assert @post.did?(:do_before_validate)
93
+ assert @post.did?(:do_after_validate)
94
+ assert @post.did?(:do_before_create)
95
+ assert @post.did?(:do_after_create)
96
+ assert @post.did?(:do_before_save)
97
+ assert @post.did?(:do_after_save)
98
+ end
99
+
100
+ should "call create / save callbacks only once" do
101
+ assert_equal 1, @post.count(:do_before_create)
102
+ assert_equal 1, @post.count(:do_after_create)
103
+ assert_equal 1, @post.count(:do_before_save)
104
+ assert_equal 1, @post.count(:do_after_create)
105
+ end
106
+ end
44
107
 
45
108
 
46
- def incr(action)
47
- val = instance_variable_get("@#{ action }")
48
- val ||= 0
49
- val += 1
109
+ context "on save of an existing object" do
110
+ setup do
111
+ @post = InstanceTypePost.create(:body => "The Body")
112
+ @post = InstanceTypePost[@post.id]
50
113
 
51
- instance_variable_set("@#{ action }", val)
52
- end
53
- end
114
+ @post.save
115
+ end
116
+
117
+ should "not call create related callbacks" do
118
+ assert ! @post.did?(:do_before_create)
119
+ assert ! @post.did?(:do_after_create)
120
+ end
121
+
122
+ should "call the rest of the callbacks" do
123
+ assert @post.did?(:do_before_validate)
124
+ assert @post.did?(:do_after_validate)
125
+ assert @post.did?(:do_before_save)
126
+ assert @post.did?(:do_after_save)
127
+ end
54
128
 
55
- context "on save when invalid state" do
56
- setup do
57
- @post = Post.new
58
- @post.save
129
+ should "call save callbacks only once" do
130
+ assert_equal 1, @post.count(:do_before_save)
131
+ assert_equal 1, @post.count(:do_after_save)
132
+ end
59
133
  end
60
134
 
61
- should "still call before / after validate" do
62
- assert @post.did?(:do_before_validate)
63
- assert @post.did?(:do_after_validate)
135
+ context "on save of an existing invalid object" do
136
+ setup do
137
+ @post = InstanceTypePost.create(:body => "The Body")
138
+ @post = InstanceTypePost[@post.id]
139
+
140
+ @post.body = nil
141
+ @post.save
142
+ end
143
+
144
+ should "call validation related callbacks" do
145
+ assert @post.did?(:do_before_validate)
146
+ assert @post.did?(:do_after_validate)
147
+ end
148
+
149
+ should "not call create related callbacks" do
150
+ assert ! @post.did?(:do_before_create)
151
+ assert ! @post.did?(:do_after_create)
152
+ end
153
+
154
+ should "also not call save related callbacks" do
155
+ assert ! @post.did?(:do_before_save)
156
+ assert ! @post.did?(:do_after_save)
157
+ end
64
158
  end
65
159
 
66
- should "not call all other callbacks" do
67
- assert ! @post.did?(:do_before_create)
68
- assert ! @post.did?(:do_after_create)
69
- assert ! @post.did?(:do_before_save)
70
- assert ! @post.did?(:do_after_save)
160
+ context "on delete" do
161
+ setup do
162
+ @post = InstanceTypePost.create(:body => "The Body")
163
+ @post = InstanceTypePost[@post.id]
164
+ @post.delete
165
+ end
166
+
167
+
168
+ should "call delete related callbacks once" do
169
+ assert_equal 1, @post.count(:do_before_delete)
170
+ assert_equal 1, @post.count(:do_after_delete)
171
+ end
172
+
173
+ should "not call all other callbacks" do
174
+ assert ! @post.did?(:do_before_validate)
175
+ assert ! @post.did?(:do_after_validate)
176
+ assert ! @post.did?(:do_before_create)
177
+ assert ! @post.did?(:do_after_create)
178
+ assert ! @post.did?(:do_before_save)
179
+ assert ! @post.did?(:do_after_save)
180
+ end
71
181
  end
72
182
  end
73
183
 
74
- context "on save when valid state" do
75
- setup do
76
- @post = Post.new(:body => "The Body")
77
- @post.save
78
- end
184
+ describe "macro level validation callbacks" do
185
+ class Post < Ohm::Model
186
+ include Ohm::Callbacks
79
187
 
80
- should "call all callbacks" do
81
- assert @post.did?(:do_before_validate)
82
- assert @post.did?(:do_after_validate)
83
- assert @post.did?(:do_before_create)
84
- assert @post.did?(:do_after_create)
85
- assert @post.did?(:do_before_save)
86
- assert @post.did?(:do_after_save)
87
- end
188
+ attribute :body
88
189
 
89
- should "call create / save callbacks only once" do
90
- assert_equal 1, @post.count(:do_before_create)
91
- assert_equal 1, @post.count(:do_after_create)
92
- assert_equal 1, @post.count(:do_before_save)
93
- assert_equal 1, @post.count(:do_after_create)
94
- end
95
- end
190
+ before :validate, :do_before_validate
191
+ after :validate, :do_after_validate
96
192
 
97
- context "on create when valid state" do
98
- setup do
99
- @post = Post.create(:body => "The Body")
100
- end
193
+ before :create, :do_before_create
194
+ after :create, :do_after_create
101
195
 
102
- should "call all callbacks" do
103
- assert @post.did?(:do_before_validate)
104
- assert @post.did?(:do_after_validate)
105
- assert @post.did?(:do_before_create)
106
- assert @post.did?(:do_after_create)
107
- assert @post.did?(:do_before_save)
108
- assert @post.did?(:do_after_save)
109
- end
196
+ before :save, :do_before_save
197
+ after :save, :do_after_save
110
198
 
111
- should "call create / save callbacks only once" do
112
- assert_equal 1, @post.count(:do_before_create)
113
- assert_equal 1, @post.count(:do_after_create)
114
- assert_equal 1, @post.count(:do_before_save)
115
- assert_equal 1, @post.count(:do_after_create)
116
- end
117
- end
199
+ before :delete, :do_before_delete
200
+ after :delete, :do_after_delete
118
201
 
202
+ def validate
203
+ super
119
204
 
120
- context "on save of an existing object" do
121
- setup do
122
- @post = Post.create(:body => "The Body")
123
- @post = Post[@post.id]
205
+ assert_present :body
206
+ end
124
207
 
125
- @post.save
126
- end
208
+ def did?(action)
209
+ instance_variable_get("@#{ action }")
210
+ end
127
211
 
128
- should "not call create related callbacks" do
129
- assert ! @post.did?(:do_before_create)
130
- assert ! @post.did?(:do_after_create)
131
- end
212
+ def count(action)
213
+ instance_variable_get("@#{ action }")
214
+ end
132
215
 
133
- should "call the rest of the callbacks" do
134
- assert @post.did?(:do_before_validate)
135
- assert @post.did?(:do_after_validate)
136
- assert @post.did?(:do_before_save)
137
- assert @post.did?(:do_after_save)
138
- end
216
+ protected
217
+ def do_before_validate() incr(:do_before_validate) end
218
+ def do_after_validate() incr(:do_after_validate) end
219
+ def do_before_create() incr(:do_before_create) end
220
+ def do_after_create() incr(:do_after_create) end
221
+ def do_before_save() incr(:do_before_save) end
222
+ def do_after_save() incr(:do_after_save) end
223
+ def do_before_delete() incr(:do_before_delete) end
224
+ def do_after_delete() incr(:do_after_delete) end
139
225
 
140
- should "call save callbacks only once" do
141
- assert_equal 1, @post.count(:do_before_save)
142
- assert_equal 1, @post.count(:do_after_save)
143
- end
144
- end
145
226
 
146
- context "on save of an existing invalid object" do
147
- setup do
148
- @post = Post.create(:body => "The Body")
149
- @post = Post[@post.id]
227
+ def incr(action)
228
+ val = instance_variable_get("@#{ action }")
229
+ val ||= 0
230
+ val += 1
150
231
 
151
- @post.body = nil
152
- @post.save
232
+ instance_variable_set("@#{ action }", val)
233
+ end
153
234
  end
154
235
 
155
- should "call validation related callbacks" do
156
- assert @post.did?(:do_before_validate)
157
- assert @post.did?(:do_after_validate)
236
+ context "on save when invalid state" do
237
+ setup do
238
+ @post = Post.new
239
+ @post.save
240
+ end
241
+
242
+ should "still call before / after validate" do
243
+ assert @post.did?(:do_before_validate)
244
+ assert @post.did?(:do_after_validate)
245
+ end
246
+
247
+ should "not call all other callbacks" do
248
+ assert ! @post.did?(:do_before_create)
249
+ assert ! @post.did?(:do_after_create)
250
+ assert ! @post.did?(:do_before_save)
251
+ assert ! @post.did?(:do_after_save)
252
+ end
158
253
  end
159
254
 
160
- should "not call create related callbacks" do
161
- assert ! @post.did?(:do_before_create)
162
- assert ! @post.did?(:do_after_create)
255
+ context "on save when valid state" do
256
+ setup do
257
+ @post = Post.new(:body => "The Body")
258
+ @post.save
259
+ end
260
+
261
+ should "call all callbacks" do
262
+ assert @post.did?(:do_before_validate)
263
+ assert @post.did?(:do_after_validate)
264
+ assert @post.did?(:do_before_create)
265
+ assert @post.did?(:do_after_create)
266
+ assert @post.did?(:do_before_save)
267
+ assert @post.did?(:do_after_save)
268
+ end
269
+
270
+ should "call create / save callbacks only once" do
271
+ assert_equal 1, @post.count(:do_before_create)
272
+ assert_equal 1, @post.count(:do_after_create)
273
+ assert_equal 1, @post.count(:do_before_save)
274
+ assert_equal 1, @post.count(:do_after_create)
275
+ end
163
276
  end
164
277
 
165
- should "also not call save related callbacks" do
166
- assert ! @post.did?(:do_before_save)
167
- assert ! @post.did?(:do_after_save)
278
+ context "on create when valid state" do
279
+ setup do
280
+ @post = Post.create(:body => "The Body")
281
+ end
282
+
283
+ should "call all callbacks" do
284
+ assert @post.did?(:do_before_validate)
285
+ assert @post.did?(:do_after_validate)
286
+ assert @post.did?(:do_before_create)
287
+ assert @post.did?(:do_after_create)
288
+ assert @post.did?(:do_before_save)
289
+ assert @post.did?(:do_after_save)
290
+ end
291
+
292
+ should "call create / save callbacks only once" do
293
+ assert_equal 1, @post.count(:do_before_create)
294
+ assert_equal 1, @post.count(:do_after_create)
295
+ assert_equal 1, @post.count(:do_before_save)
296
+ assert_equal 1, @post.count(:do_after_create)
297
+ end
168
298
  end
169
- end
170
299
 
171
- context "on delete" do
172
- setup do
173
- @post = Post.create(:body => "The Body")
174
- @post = Post[@post.id]
175
- @post.delete
176
- end
177
300
 
301
+ context "on save of an existing object" do
302
+ setup do
303
+ @post = Post.create(:body => "The Body")
304
+ @post = Post[@post.id]
305
+
306
+ @post.save
307
+ end
308
+
309
+ should "not call create related callbacks" do
310
+ assert ! @post.did?(:do_before_create)
311
+ assert ! @post.did?(:do_after_create)
312
+ end
313
+
314
+ should "call the rest of the callbacks" do
315
+ assert @post.did?(:do_before_validate)
316
+ assert @post.did?(:do_after_validate)
317
+ assert @post.did?(:do_before_save)
318
+ assert @post.did?(:do_after_save)
319
+ end
320
+
321
+ should "call save callbacks only once" do
322
+ assert_equal 1, @post.count(:do_before_save)
323
+ assert_equal 1, @post.count(:do_after_save)
324
+ end
325
+ end
178
326
 
179
- should "call delete related callbacks once" do
180
- assert_equal 1, @post.count(:do_before_delete)
181
- assert_equal 1, @post.count(:do_after_delete)
327
+ context "on save of an existing invalid object" do
328
+ setup do
329
+ @post = Post.create(:body => "The Body")
330
+ @post = Post[@post.id]
331
+
332
+ @post.body = nil
333
+ @post.save
334
+ end
335
+
336
+ should "call validation related callbacks" do
337
+ assert @post.did?(:do_before_validate)
338
+ assert @post.did?(:do_after_validate)
339
+ end
340
+
341
+ should "not call create related callbacks" do
342
+ assert ! @post.did?(:do_before_create)
343
+ assert ! @post.did?(:do_after_create)
344
+ end
345
+
346
+ should "also not call save related callbacks" do
347
+ assert ! @post.did?(:do_before_save)
348
+ assert ! @post.did?(:do_after_save)
349
+ end
182
350
  end
183
351
 
184
- should "not call all other callbacks" do
185
- assert ! @post.did?(:do_before_validate)
186
- assert ! @post.did?(:do_after_validate)
187
- assert ! @post.did?(:do_before_create)
188
- assert ! @post.did?(:do_after_create)
189
- assert ! @post.did?(:do_before_save)
190
- assert ! @post.did?(:do_after_save)
352
+ context "on delete" do
353
+ setup do
354
+ @post = Post.create(:body => "The Body")
355
+ @post = Post[@post.id]
356
+ @post.delete
357
+ end
358
+
359
+
360
+ should "call delete related callbacks once" do
361
+ assert_equal 1, @post.count(:do_before_delete)
362
+ assert_equal 1, @post.count(:do_after_delete)
363
+ end
364
+
365
+ should "not call all other callbacks" do
366
+ assert ! @post.did?(:do_before_validate)
367
+ assert ! @post.did?(:do_after_validate)
368
+ assert ! @post.did?(:do_before_create)
369
+ assert ! @post.did?(:do_after_create)
370
+ assert ! @post.did?(:do_before_save)
371
+ assert ! @post.did?(:do_after_save)
372
+ end
191
373
  end
192
374
  end
193
375
  end
@@ -0,0 +1,165 @@
1
+ require "helper"
2
+
3
+ class LunarMacrosTest < Test::Unit::TestCase
4
+ setup do
5
+ Ohm.flush
6
+ end
7
+
8
+ class Post < Ohm::Model
9
+ include Ohm::LunarMacros
10
+ end
11
+
12
+ test "fuzzy / text / number / sortable" do
13
+ Post.fuzzy :name
14
+ assert_equal [:name], Post.fuzzy
15
+
16
+ Post.text :name
17
+ assert_equal [:name], Post.text
18
+
19
+ Post.number :name
20
+ assert_equal [:name], Post.number
21
+
22
+ Post.sortable :name
23
+ assert_equal [:name], Post.sortable
24
+ end
25
+
26
+ test "fuzzy / text / number / sortable done twice" do
27
+ Post.fuzzy :name
28
+ Post.fuzzy :name
29
+ assert_equal [:name], Post.fuzzy
30
+
31
+ Post.text :name
32
+ Post.text :name
33
+ assert_equal [:name], Post.text
34
+
35
+ Post.number :name
36
+ Post.number :name
37
+ assert_equal [:name], Post.number
38
+
39
+ Post.sortable :name
40
+ Post.sortable :name
41
+ assert_equal [:name], Post.sortable
42
+ end
43
+
44
+ context "on create" do
45
+ class Document < Ohm::Model
46
+ include Ohm::LunarMacros
47
+
48
+ fuzzy :filename
49
+ text :content
50
+ number :author_id
51
+ sortable :views
52
+
53
+ def filename() "Filename" end
54
+ def content() "Content" end
55
+ def author_id() 100 end
56
+ def views() 15 end
57
+ end
58
+
59
+ test "indexes filename" do
60
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
61
+ Lunar.expects(:index).with(Document).yields(doc)
62
+
63
+ doc.expects(:id).with('1')
64
+ doc.expects(:fuzzy).with(:filename, 'Filename')
65
+ doc = Document.create
66
+ end
67
+
68
+ test "indexes content" do
69
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
70
+ Lunar.expects(:index).with(Document).yields(doc)
71
+
72
+ doc.expects(:id).with('1')
73
+ doc.expects(:text).with(:content, 'Content')
74
+ doc = Document.create
75
+ end
76
+
77
+ test "indexes number" do
78
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
79
+ Lunar.expects(:index).with(Document).yields(doc)
80
+
81
+ doc.expects(:id).with('1')
82
+ doc.expects(:number).with(:author_id, 100)
83
+ doc = Document.create
84
+ end
85
+
86
+ test "indexes sortable" do
87
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
88
+ Lunar.expects(:index).with(Document).yields(doc)
89
+
90
+ doc.expects(:id).with('1')
91
+ doc.expects(:sortable).with(:views, 15)
92
+ doc = Document.create
93
+ end
94
+ end
95
+
96
+ context "on update" do
97
+ class Document < Ohm::Model
98
+ include Ohm::LunarMacros
99
+
100
+ fuzzy :filename
101
+ text :content
102
+ number :author_id
103
+ sortable :views
104
+
105
+ def filename() "Filename" end
106
+ def content() "Content" end
107
+ def author_id() 100 end
108
+ def views() 15 end
109
+ end
110
+
111
+ test "indexes filename" do
112
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
113
+ Lunar.expects(:index).times(2).with(Document).yields(doc)
114
+
115
+ doc.expects(:id).times(2).with('1')
116
+ doc.expects(:fuzzy).times(2).with(:filename, 'Filename')
117
+ doc = Document.create
118
+ doc.save
119
+ end
120
+
121
+ test "indexes content" do
122
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
123
+ Lunar.expects(:index).times(2).with(Document).yields(doc)
124
+
125
+ doc.expects(:id).times(2).with('1')
126
+ doc.expects(:text).times(2).with(:content, 'Content')
127
+ doc = Document.create
128
+ doc.save
129
+ end
130
+
131
+ test "indexes number" do
132
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
133
+ Lunar.expects(:index).times(2).with(Document).yields(doc)
134
+
135
+ doc.expects(:id).times(2).with('1')
136
+ doc.expects(:number).times(2).with(:author_id, 100)
137
+ doc = Document.create
138
+ doc.save
139
+ end
140
+
141
+ test "indexes sortable" do
142
+ doc = stub("Doc", fuzzy: nil, text: nil, number: nil, sortable: nil)
143
+ Lunar.expects(:index).times(2).with(Document).yields(doc)
144
+
145
+ doc.expects(:id).times(2).with('1')
146
+ doc.expects(:sortable).times(2).with(:views, 15)
147
+ doc = Document.create
148
+ doc.save
149
+ end
150
+ end
151
+
152
+ context "on delete" do
153
+ test "executes Lunar.delete" do
154
+ doc = stub("Doc", id: nil, fuzzy: nil, text: nil, number: nil,
155
+ sortable: nil)
156
+
157
+ Lunar.expects(:index).with(Document).yields(doc)
158
+
159
+ doc = Document.create
160
+
161
+ Lunar.expects(:delete).with(Document, '1')
162
+ doc.delete
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,29 @@
1
+ require "helper"
2
+
3
+ class OhmSlugTest < Test::Unit::TestCase
4
+ module Finder
5
+ def [](id)
6
+ new(id)
7
+ end
8
+ end
9
+
10
+ class BaseWithoutToParam < Struct.new(:id)
11
+ extend Finder
12
+
13
+ include Ohm::Slug
14
+
15
+ def to_s
16
+ "A very Unique and Interesting String?'"
17
+ end
18
+ end
19
+
20
+ test "to_param" do
21
+ obj = BaseWithoutToParam.new(1)
22
+
23
+ assert_equal '1-a-very-unique-and-interesting-string', obj.to_param
24
+ end
25
+
26
+ test "finding" do
27
+ assert_equal 1, BaseWithoutToParam['1-a-very-unique'].id
28
+ end
29
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 27
9
- version: 0.0.27
8
+ - 28
9
+ version: 0.0.28
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cyril David
@@ -14,14 +14,13 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-29 00:00:00 +08:00
17
+ date: 2010-07-02 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: contest
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
24
  requirements:
26
25
  - - ">="
27
26
  - !ruby/object:Gem::Version
@@ -34,7 +33,6 @@ dependencies:
34
33
  name: redis
35
34
  prerelease: false
36
35
  requirement: &id002 !ruby/object:Gem::Requirement
37
- none: false
38
36
  requirements:
39
37
  - - ">="
40
38
  - !ruby/object:Gem::Version
@@ -47,7 +45,6 @@ dependencies:
47
45
  name: ohm
48
46
  prerelease: false
49
47
  requirement: &id003 !ruby/object:Gem::Requirement
50
- none: false
51
48
  requirements:
52
49
  - - ">="
53
50
  - !ruby/object:Gem::Version
@@ -60,7 +57,6 @@ dependencies:
60
57
  name: timecop
61
58
  prerelease: false
62
59
  requirement: &id004 !ruby/object:Gem::Requirement
63
- none: false
64
60
  requirements:
65
61
  - - ">="
66
62
  - !ruby/object:Gem::Version
@@ -73,7 +69,6 @@ dependencies:
73
69
  name: mocha
74
70
  prerelease: false
75
71
  requirement: &id005 !ruby/object:Gem::Requirement
76
- none: false
77
72
  requirements:
78
73
  - - ">="
79
74
  - !ruby/object:Gem::Version
@@ -82,6 +77,18 @@ dependencies:
82
77
  version: "0"
83
78
  type: :development
84
79
  version_requirements: *id005
80
+ - !ruby/object:Gem::Dependency
81
+ name: lunar
82
+ prerelease: false
83
+ requirement: &id006 !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id006
85
92
  description: Highly decoupled drop-in functionality for Ohm models
86
93
  email: cyx.ucron@gmail.com
87
94
  executables: []
@@ -104,7 +111,9 @@ files:
104
111
  - lib/ohm/contrib/date_validations.rb
105
112
  - lib/ohm/contrib/extra_validations.rb
106
113
  - lib/ohm/contrib/locking.rb
114
+ - lib/ohm/contrib/lunar_macros.rb
107
115
  - lib/ohm/contrib/number_validations.rb
116
+ - lib/ohm/contrib/slug.rb
108
117
  - lib/ohm/contrib/timestamping.rb
109
118
  - lib/ohm/contrib/to_hash.rb
110
119
  - lib/ohm/contrib/typecast.rb
@@ -116,7 +125,9 @@ files:
116
125
  - test/test_ohm_contrib_callbacks.rb
117
126
  - test/test_ohm_date_validations.rb
118
127
  - test/test_ohm_extra_validations.rb
128
+ - test/test_ohm_lunar_macros.rb
119
129
  - test/test_ohm_number_validations.rb
130
+ - test/test_ohm_slug.rb
120
131
  - test/test_ohm_timestamping.rb
121
132
  - test/test_ohm_to_hash.rb
122
133
  - test/test_ohm_typecast.rb
@@ -131,7 +142,6 @@ rdoc_options:
131
142
  require_paths:
132
143
  - lib
133
144
  required_ruby_version: !ruby/object:Gem::Requirement
134
- none: false
135
145
  requirements:
136
146
  - - ">="
137
147
  - !ruby/object:Gem::Version
@@ -139,7 +149,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
149
  - 0
140
150
  version: "0"
141
151
  required_rubygems_version: !ruby/object:Gem::Requirement
142
- none: false
143
152
  requirements:
144
153
  - - ">="
145
154
  - !ruby/object:Gem::Version
@@ -149,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
158
  requirements: []
150
159
 
151
160
  rubyforge_project:
152
- rubygems_version: 1.3.7
161
+ rubygems_version: 1.3.6
153
162
  signing_key:
154
163
  specification_version: 3
155
164
  summary: A collection of ohm related modules
@@ -160,7 +169,9 @@ test_files:
160
169
  - test/test_ohm_contrib_callbacks.rb
161
170
  - test/test_ohm_date_validations.rb
162
171
  - test/test_ohm_extra_validations.rb
172
+ - test/test_ohm_lunar_macros.rb
163
173
  - test/test_ohm_number_validations.rb
174
+ - test/test_ohm_slug.rb
164
175
  - test/test_ohm_timestamping.rb
165
176
  - test/test_ohm_to_hash.rb
166
177
  - test/test_ohm_typecast.rb