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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +203 -0
- data/README.md +155 -0
- data/Rakefile +22 -0
- data/couchbase-jruby-model.gemspec +27 -0
- data/lib/couchbase-jruby-model.rb +23 -0
- data/lib/couchbase/active_model.rb +69 -0
- data/lib/couchbase/model.rb +859 -0
- data/lib/couchbase/model/configuration.rb +30 -0
- data/lib/couchbase/model/ext/camelize.rb +23 -0
- data/lib/couchbase/model/ext/constantize.rb +29 -0
- data/lib/couchbase/model/ext/singleton_class.rb +24 -0
- data/lib/couchbase/model/uuid.rb +113 -0
- data/lib/couchbase/model/version.rb +26 -0
- data/lib/couchbase/railtie.rb +142 -0
- data/lib/rails/generators/couchbase/config/config_generator.rb +43 -0
- data/lib/rails/generators/couchbase/config/templates/couchbase.yml +23 -0
- data/lib/rails/generators/couchbase/view/templates/map.js +40 -0
- data/lib/rails/generators/couchbase/view/templates/reduce.js +61 -0
- data/lib/rails/generators/couchbase/view/view_generator.rb +43 -0
- data/lib/rails/generators/couchbase_generator.rb +42 -0
- data/tasks/package.rake +27 -0
- data/tasks/test.rake +34 -0
- data/tasks/util.rake +21 -0
- data/test/setup.rb +168 -0
- data/test/test_active_model_integration.rb +124 -0
- data/test/test_model.rb +311 -0
- data/test/test_model_rails_integration.rb +76 -0
- data/test/test_uuid.rb +32 -0
- metadata +151 -0
@@ -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
|
data/test/test_model.rb
ADDED
@@ -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
|