couchbase-jruby-model 0.1.0-java

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.
@@ -0,0 +1,124 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+
20
+ class ActiveUser < Couchbase::Model
21
+ attribute :name
22
+ attribute :email
23
+ attribute :role
24
+ attribute :created_at, :updated_at, :default => lambda { Time.now.utc }
25
+
26
+ validates_presence_of :email
27
+ validates :role, :presence => true, :inclusion => { :in => %w(admin editor) }
28
+
29
+ before_create :upcase_name
30
+
31
+ private
32
+
33
+ def upcase_name
34
+ self.name = self.name.upcase unless self.name.nil?
35
+ end
36
+ end
37
+
38
+ class ActiveObj < Couchbase::Model
39
+ end
40
+
41
+ class TestActiveModelIntegration < MiniTest::Unit::TestCase
42
+
43
+ include ActiveModel::Lint::Tests
44
+
45
+ def setup
46
+ @model = ActiveUser.new # used by ActiveModel::Lint::Tests
47
+ @mock = start_mock
48
+ bucket = Couchbase.connect(:hostname => @mock.host, :port => @mock.port)
49
+ ActiveObj.bucket = ActiveUser.bucket = bucket
50
+ end
51
+
52
+ def teardown
53
+ stop_mock(@mock)
54
+ end
55
+
56
+ def test_active_model_includes
57
+ [
58
+ ActiveModel::Conversion,
59
+ ActiveModel::Validations,
60
+ ActiveModel::Validations::Callbacks,
61
+ ActiveModel::Validations::HelperMethods
62
+ ].each do |mod|
63
+ assert ActiveUser.ancestors.include?(mod), "Model not including #{mod}"
64
+ end
65
+ end
66
+
67
+ def test_callbacks
68
+ [
69
+ :before_validation, :after_validation,
70
+ :after_initialize, :before_create, :around_create,
71
+ :after_create, :before_delete, :around_delete,
72
+ :after_delete, :before_save, :around_save, :after_save,
73
+ :before_update, :around_update, :after_update
74
+ ].each do |callback|
75
+ assert ActiveObj.respond_to?(callback), "Model doesn't support callback: #{callback}"
76
+ end
77
+ end
78
+
79
+ def test_active_model_validations
80
+ no_role = ActiveUser.new(:email => 'joe@example.com', :role => nil)
81
+ bad_role = ActiveUser.new(:email => 'joe@example.com', :role => 'bad')
82
+ good_role = ActiveUser.new(:email => 'joe@example.com', :role => 'admin')
83
+
84
+ refute no_role.valid?
85
+ refute bad_role.valid?
86
+ assert good_role.valid?
87
+ end
88
+
89
+ def test_active_model_validation_helpers
90
+ valid = ActiveUser.new(:email => 'joe@example.com', :role => 'editor')
91
+ invalid = ActiveUser.new(:name => 'Joe', :role => 'editor')
92
+
93
+ assert valid.valid?
94
+ refute invalid.valid?
95
+ end
96
+
97
+ def test_before_save_callback
98
+ assert user = ActiveUser.create(:name => 'joe', :role => 'admin', :email => 'joe@example.com')
99
+ assert_equal 'JOE', user.name
100
+ end
101
+
102
+ def test_model_name_exposes_singular_and_human_name
103
+ assert_equal 'active_user', @model.class.model_name.singular
104
+ assert_equal 'Active user', @model.class.model_name.human
105
+ end
106
+
107
+ def test_model_equality
108
+ obj1 = ActiveObj.create
109
+ obj2 = ActiveObj.find(obj1.id)
110
+
111
+ assert_equal obj1, obj2
112
+ end
113
+
114
+ def test_to_key
115
+ assert_equal ['the-id'], ActiveObj.new(:id => 'the-id').to_key
116
+ assert_equal ['the-key'], ActiveObj.new(:key => 'the-key').to_key
117
+ end
118
+
119
+ def test_to_param
120
+ assert_equal 'the-id', ActiveObj.new(:id => 'the-id').to_param
121
+ assert_equal 'the-key', ActiveObj.new(:key => ['the', 'key']).to_param
122
+ end
123
+
124
+ end
@@ -0,0 +1,311 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+
20
+ class Post < Couchbase::Model
21
+ attribute :title
22
+ attribute :body
23
+ attribute :author, :default => 'Anonymous'
24
+ attribute :created_at, :default => lambda { Time.utc('2010-01-01') }
25
+ end
26
+
27
+ class ValidPost < Couchbase::Model
28
+ attribute :title
29
+
30
+ def valid?
31
+ title && !title.empty?
32
+ end
33
+ end
34
+
35
+ class Brewery < Couchbase::Model
36
+ attribute :name
37
+ end
38
+
39
+ class Beer < Couchbase::Model
40
+ attribute :name
41
+ belongs_to :brewery
42
+ end
43
+
44
+ class Attachment < Couchbase::Model
45
+ defaults :format => :plain
46
+ end
47
+
48
+ class Comments < Couchbase::Model
49
+ include Enumerable
50
+ attribute :comments, :default => []
51
+ end
52
+
53
+ class User < Couchbase::Model
54
+ design_document :people
55
+ end
56
+
57
+ class TestModel < MiniTest::Unit::TestCase
58
+
59
+ def setup
60
+ @mock = start_mock
61
+ bucket = Couchbase.connect(:hostname => @mock.host, :port => @mock.port)
62
+ [Post, ValidPost, Brewery, Beer, Attachment].each do |model|
63
+ model.bucket = bucket
64
+ end
65
+ end
66
+
67
+ def teardown
68
+ stop_mock(@mock)
69
+ end
70
+
71
+ def test_design_document
72
+ assert_equal 'people', User.design_document
73
+ assert_equal 'new_people', User.design_document('new_people')
74
+ assert_equal 'post', Post.design_document
75
+ end
76
+
77
+ def test_it_supports_value_property
78
+ doc = {
79
+ 'id' => 'x',
80
+ 'key' => 'x',
81
+ 'value' => 'x',
82
+ 'doc' => {
83
+ 'value' => {'title' => 'foo'}
84
+ }
85
+ }
86
+ post = Post.wrap(Post.bucket, doc)
87
+ assert_equal 'foo', post.title
88
+ end
89
+
90
+ def test_it_supports_json_property
91
+ doc = {
92
+ 'id' => 'x',
93
+ 'key' => 'x',
94
+ 'value' => 'x',
95
+ 'doc' => {
96
+ 'json' => {'title' => 'foo'}
97
+ }
98
+ }
99
+ post = Post.wrap(Post.bucket, doc)
100
+ assert_equal 'foo', post.title
101
+ end
102
+
103
+ def test_assigns_attributes_from_the_hash
104
+ post = Post.new(:title => 'Hello, world')
105
+ assert_equal 'Hello, world', post.title
106
+ refute post.body
107
+ refute post.id
108
+ end
109
+
110
+ def test_uses_default_value_or_nil
111
+ post = Post.new(:title => 'Hello, world')
112
+ refute post.body
113
+ assert_equal 'Anonymous', post.author
114
+ assert_equal 'Anonymous', post.attributes[:author]
115
+ end
116
+
117
+ def test_allows_lambda_as_default_value
118
+ post = Post.new(:title => 'Hello, world')
119
+ expected = Time.utc('2010-01-01')
120
+ assert_equal expected, post.created_at
121
+ assert_equal expected, post.attributes[:created_at]
122
+ end
123
+
124
+ def test_assings_id_and_saves_the_object
125
+ post = Post.create(:title => 'Hello, world')
126
+ assert post.id
127
+ end
128
+
129
+ def test_updates_attributes
130
+ post = Post.create(:title => 'Hello, world')
131
+ post.update(:body => 'This is my first example')
132
+ assert_equal 'This is my first example', post.body
133
+ end
134
+
135
+ def test_refreshes_the_attributes_with_reload_method
136
+ orig = Post.create(:title => 'Hello, world')
137
+ double = Post.find(orig.id)
138
+ double.update(:title => 'Good bye, world')
139
+ orig.reload
140
+ assert_equal 'Good bye, world', orig.title
141
+ end
142
+
143
+ def test_reloads_cas_value_with_reload_method
144
+ orig = Post.create(:title => "Hello, world")
145
+ double = Post.find(orig.id)
146
+ orig.update(:title => "Good bye, world")
147
+ double.reload
148
+
149
+ assert_equal orig.meta[:cas], double.meta[:cas]
150
+ end
151
+
152
+ def test_it_raises_not_found_exception
153
+ assert_raises Couchbase::Error::NotFound do
154
+ Post.find('missing_key')
155
+ end
156
+ end
157
+
158
+ def test_it_returns_nil_when_key_not_found
159
+ refute Post.find_by_id('missing_key')
160
+ end
161
+
162
+ def test_doesnt_raise_if_the_attribute_redefined
163
+ eval <<-EOC
164
+ class RefinedPost < Couchbase::Model
165
+ attribute :title
166
+ attribute :title
167
+ end
168
+ EOC
169
+ end
170
+
171
+ def test_allows_to_define_several_attributes_at_once
172
+ eval <<-EOC
173
+ class Comment < Couchbase::Model
174
+ attribute :name, :email, :body
175
+ end
176
+ EOC
177
+
178
+ comment = Comment.new
179
+ assert_respond_to comment, :name
180
+ assert_respond_to comment, :email
181
+ assert_respond_to comment, :body
182
+ end
183
+
184
+ def test_allows_arbitrary_ids
185
+ Post.create(:id => uniq_id, :title => 'Foo')
186
+ assert_equal 'Foo', Post.find(uniq_id).title
187
+ end
188
+
189
+ def test_returns_an_instance_of_post
190
+ Post.bucket.set(uniq_id, {:title => 'foo'})
191
+ assert Post.find(uniq_id).kind_of?(Post)
192
+ assert_equal uniq_id, Post.find(uniq_id).id
193
+ assert_equal 'foo', Post.find(uniq_id).title
194
+ end
195
+
196
+ def test_changes_its_attributes
197
+ post = Post.create(:title => 'Hello, world')
198
+ post.title = 'Good bye, world'
199
+ post.save.reload
200
+ assert_equal 'Good bye, world', post.title
201
+ end
202
+
203
+ def test_assings_a_new_id_to_each_record
204
+ post1 = Post.create
205
+ post2 = Post.create
206
+
207
+ refute post1.new?
208
+ refute post2.new?
209
+ refute_equal post1.id, post2.id
210
+ end
211
+
212
+ def test_deletes_an_existent_model
213
+ post = Post.create(:id => uniq_id)
214
+ assert post.delete
215
+ assert_raises Couchbase::Error::NotFound do
216
+ Post.bucket.get(uniq_id)
217
+ end
218
+ end
219
+
220
+ def test_fails_to_delete_model_without_id
221
+ post = Post.new(:title => 'Hello')
222
+ refute post.id
223
+ assert_raises Couchbase::Error::MissingId do
224
+ post.delete
225
+ end
226
+ end
227
+
228
+ def test_belongs_to_assoc
229
+ brewery = Brewery.create(:name => 'Anheuser-Busch')
230
+ assert_includes Beer.attributes.keys, :brewery_id
231
+ beer = Beer.create(:name => 'Budweiser', :brewery_id => brewery.id)
232
+ assert_respond_to beer, :brewery
233
+ assoc = beer.brewery
234
+ assert_instance_of Brewery, assoc
235
+ assert_equal 'Anheuser-Busch', assoc.name
236
+ end
237
+
238
+ def test_to_key
239
+ assert_equal ['the-id'], Post.new(:id => 'the-id').to_key
240
+ assert_equal ['the-key'], Post.new(:key => 'the-key').to_key
241
+ end
242
+
243
+ def test_to_param
244
+ assert_equal 'the-id', Post.new(:id => 'the-id').to_param
245
+ assert_equal 'the-key', Post.new(:key => ['the', 'key']).to_param
246
+ end
247
+
248
+ def test_as_json
249
+ require 'active_support/json/encoding'
250
+
251
+ response = {'id' => 'the-id'}
252
+ assert_equal response, Post.new(:id => 'the-id').as_json
253
+
254
+ response = {}
255
+ assert_equal response, Post.new(:id => 'the-id').as_json(:except => :id)
256
+ end
257
+
258
+ def test_validation
259
+ post = ValidPost.create(:title => 'Hello, World!')
260
+ assert post.valid?, 'post with title should be valid'
261
+ post.title = nil
262
+ refute post.save
263
+ assert_raises(Couchbase::Error::RecordInvalid) do
264
+ post.save!
265
+ end
266
+ refute ValidPost.create(:title => nil)
267
+ assert_raises(Couchbase::Error::RecordInvalid) do
268
+ ValidPost.create!(:title => nil)
269
+ end
270
+ end
271
+
272
+ def test_blob_documents
273
+ contents = File.read(__FILE__)
274
+ id = Attachment.create(:raw => contents).id
275
+ blob = Attachment.find(id)
276
+ assert_equal contents, blob.raw
277
+ end
278
+
279
+ def test_couchbase_ancestor
280
+ assert_equal Couchbase::Model, Comments.couchbase_ancestor
281
+ end
282
+
283
+ def test_returns_multiple_instances_of_post
284
+ Post.create(:id => uniq_id('first'), :title => 'foo')
285
+ Post.create(:id => uniq_id('second'), :title => 'bar')
286
+
287
+ results = Post.find([uniq_id('first'), uniq_id('second')])
288
+ assert results.kind_of?(Array)
289
+ assert results.size == 2
290
+ assert results.detect { |post| post.id == uniq_id('first') }.title == 'foo'
291
+ assert results.detect { |post| post.id == uniq_id('second') }.title == 'bar'
292
+ end
293
+
294
+ def test_returns_array_for_array_of_ids
295
+ Post.create(:id => uniq_id('first'), :title => 'foo')
296
+
297
+ results = Post.find([uniq_id('first')])
298
+ assert results.kind_of?(Array)
299
+ assert results.size == 1
300
+ assert results[0].title == 'foo'
301
+ end
302
+
303
+ def test_returns_array_for_array_of_ids_using_find_by_id
304
+ Post.create(:id => uniq_id('first'), :title => 'foo')
305
+
306
+ results = Post.find_by_id([uniq_id('first')])
307
+ assert results.kind_of?(Array)
308
+ assert results.size == 1
309
+ assert results[0].title == 'foo'
310
+ end
311
+ end
@@ -0,0 +1,76 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011, 2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require File.join(File.dirname(__FILE__), 'setup')
19
+
20
+ class Program < Couchbase::Model
21
+ attribute :title
22
+ attribute :genres, :default => []
23
+ end
24
+
25
+ class Movie < Program
26
+ attribute :mpaa_rating
27
+ attribute :runtime
28
+ end
29
+
30
+ class Series < Program
31
+ attribute :vchip_rating
32
+ end
33
+
34
+ class Episode < Series
35
+ attribute :runtime
36
+ end
37
+
38
+ class TestModelRailsIntegration < MiniTest::Unit::TestCase
39
+
40
+ def test_class_attributes_are_inheritable
41
+ program_attributes = [:title, :genres]
42
+ movie_attributes = [:mpaa_rating, :runtime]
43
+ series_attributes = [:vchip_rating]
44
+ episode_attributes = [:runtime]
45
+
46
+ assert_equal program_attributes, Program.attributes.keys
47
+ assert_equal program_attributes + movie_attributes, Movie.attributes.keys
48
+ assert_equal program_attributes + series_attributes, Series.attributes.keys
49
+ assert_equal program_attributes + series_attributes + episode_attributes, Episode.attributes.keys
50
+ end
51
+
52
+ def test_default_attributes_are_inheritable
53
+ assert_equal nil, Movie.attributes[:title]
54
+ assert_equal [], Movie.attributes[:genres]
55
+ end
56
+
57
+ def test_instance_attributes_are_inheritable
58
+ episode = Episode.new(:title => 'Family Guy', :genres => ['Comedy'], :vchip_rating => 'TVPG', :runtime => 30)
59
+
60
+ assert_equal [:title, :genres, :vchip_rating, :runtime], episode.attributes.keys
61
+ assert_equal 'Family Guy', episode.title
62
+ assert_equal ['Comedy'], episode.genres
63
+ assert_equal 30, episode.runtime
64
+ assert_equal 'TVPG', episode.vchip_rating
65
+ end
66
+
67
+ def test_class_attributes_from_subclasses_do_not_propogate_up_ancestor_chain
68
+ assert_equal [:title, :genres, :vchip_rating], Series.attributes.keys
69
+ end
70
+
71
+ def test_instance_attributes_from_subclasses_do_not_propogate_up_ancestor_chain
72
+ series = Series.new(:title => 'Family Guy', :genres => ['Comedy'], :vchip_rating => 'TVPG')
73
+ assert_equal [:title, :genres, :vchip_rating], series.attributes.keys
74
+ end
75
+
76
+ end