rasti-db 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,494 @@
1
+ require 'minitest_helper'
2
+
3
+ describe 'Collection' do
4
+
5
+ describe 'Specification' do
6
+
7
+ it 'Implicit' do
8
+ Users.collection_name.must_equal :users
9
+ Users.model.must_equal User
10
+ Users.primary_key.must_equal :id
11
+ Users.implicit_foreign_key_name.must_equal :user_id
12
+ end
13
+
14
+ it 'Explicit' do
15
+ model_class = Rasti::DB::Model[:code, :name]
16
+
17
+ collection_class = Class.new(Rasti::DB::Collection) do
18
+ set_collection_name :countries
19
+ set_primary_key :code
20
+ set_model model_class
21
+ end
22
+
23
+ collection_class.collection_name.must_equal :countries
24
+ collection_class.model.must_equal model_class
25
+ collection_class.primary_key.must_equal :code
26
+ end
27
+
28
+ it 'Lazy model name' do
29
+ collection_class = Class.new(Rasti::DB::Collection) do
30
+ set_model :User
31
+ end
32
+
33
+ collection_class.model.must_equal User
34
+ end
35
+
36
+ end
37
+
38
+ describe 'Insert, Update and Delete' do
39
+
40
+ it 'Insert' do
41
+ id = users.insert name: 'User 1'
42
+
43
+ db[:users][id: id][:name].must_equal 'User 1'
44
+ end
45
+
46
+ it 'Insert with many to many' do
47
+ user_id = db[:users].insert name: 'User 1'
48
+
49
+ 1.upto(2) do |i|
50
+ db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...'
51
+ db[:categories].insert name: "Category #{i}"
52
+ end
53
+
54
+ post_id = posts.insert user_id: user_id, title: 'Post title', body: '...', categories: [1,2]
55
+ category_id = categories.insert name: 'Category', posts: [1,2]
56
+
57
+ db[:categories_posts].where(post_id: post_id).map(:category_id).must_equal [1,2]
58
+ db[:categories_posts].where(category_id: category_id).map(:post_id).must_equal [1,2]
59
+ end
60
+
61
+ it 'Insert only many to many' do
62
+ 1.upto(3) do |i|
63
+ db[:categories].insert name: "Category #{i}"
64
+ end
65
+
66
+ user_id = db[:users].insert name: 'User 1'
67
+ post_id = db[:posts].insert user_id: user_id, title: 'Post title', body: '...'
68
+ 1.upto(2) { |category_id| db[:categories_posts].insert post_id: post_id, category_id: category_id }
69
+
70
+ posts.insert_relations post_id, categories: [3]
71
+
72
+ db[:categories_posts].where(post_id: post_id).map(:category_id).must_equal [1,2,3]
73
+ end
74
+
75
+ it 'Bulk insert' do
76
+ users_attrs = 1.upto(2).map { |i| {name: "User #{i}"} }
77
+
78
+ ids = users.bulk_insert users_attrs, return: :primary_key
79
+
80
+ ids.must_equal [1,2]
81
+ db[:users][id: 1][:name].must_equal 'User 1'
82
+ db[:users][id: 2][:name].must_equal 'User 2'
83
+ end
84
+
85
+ it 'Update' do
86
+ id = db[:users].insert name: 'User 1'
87
+
88
+ db[:users][id: id][:name].must_equal 'User 1'
89
+
90
+ users.update id, name: 'updated'
91
+
92
+ db[:users][id: id][:name].must_equal 'updated'
93
+ end
94
+
95
+ it 'Update with many to many' do
96
+ user_id = db[:users].insert name: 'User 1'
97
+
98
+ 1.upto(3) do |i|
99
+ db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...'
100
+ db[:categories].insert name: "Category #{i}"
101
+ end
102
+
103
+ db[:categories_posts].insert post_id: 1, category_id: 1
104
+ db[:categories_posts].insert post_id: 1, category_id: 2
105
+ db[:categories_posts].insert post_id: 2, category_id: 2
106
+
107
+ db[:categories_posts].where(post_id: 1).map(:category_id).must_equal [1,2]
108
+
109
+ posts.update 1, categories: [2,3]
110
+
111
+ db[:categories_posts].where(post_id: 1).map(:category_id).must_equal [2,3]
112
+
113
+ db[:categories_posts].where(category_id: 2).map(:post_id).must_equal [1,2]
114
+
115
+ categories.update 2, posts: [2,3]
116
+
117
+ db[:categories_posts].where(category_id: 2).map(:post_id).must_equal [2,3]
118
+ end
119
+
120
+ it 'Bulk update' do
121
+ user_id = db[:users].insert name: 'User 1'
122
+ 1.upto(3) { |i| db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...' }
123
+
124
+ posts.bulk_update(body: 'Updated ...') { where id: [1,2] }
125
+
126
+ db[:posts][id: 1][:body].must_equal 'Updated ...'
127
+ db[:posts][id: 2][:body].must_equal 'Updated ...'
128
+ db[:posts][id: 3][:body].must_equal '...'
129
+ end
130
+
131
+ it 'Delete' do
132
+ id = db[:users].insert name: 'User 1'
133
+
134
+ db[:users].count.must_equal 1
135
+
136
+ users.delete id
137
+
138
+ db[:users].count.must_equal 0
139
+ end
140
+
141
+ it 'Delete only many to many' do
142
+ 1.upto(3) do |i|
143
+ db[:categories].insert name: "Category #{i}"
144
+ end
145
+
146
+ user_id = db[:users].insert name: 'User 1'
147
+ post_id = db[:posts].insert user_id: user_id, title: 'Post title', body: '...'
148
+ 1.upto(3) { |category_id| db[:categories_posts].insert post_id: post_id, category_id: category_id }
149
+
150
+ posts.delete_relations post_id, categories: [3]
151
+
152
+ db[:categories_posts].where(post_id: post_id).map(:category_id).must_equal [1,2]
153
+ end
154
+
155
+ it 'Bulk delete' do
156
+ 1.upto(3) { |i| db[:users].insert name: "User #{i}" }
157
+
158
+ users.bulk_delete { where id: [1,2] }
159
+
160
+ db[:users].map(:id).must_equal [3]
161
+ end
162
+
163
+ describe 'Delete cascade' do
164
+
165
+ before :each do
166
+ 1.upto(3) do |i|
167
+ user_id = db[:users].insert name: "User #{i}"
168
+ category_id = db[:categories].insert name: "Category #{i}"
169
+
170
+ 1.upto(3) do |n|
171
+ post_id = db[:posts].insert user_id: user_id, title: "Post #{i}.#{n}", body: '...'
172
+ db[:categories_posts].insert post_id: post_id, category_id: category_id
173
+ end
174
+ end
175
+
176
+ {1 => 4..6, 2 => 7..9, 3 => 1..3}.each do |user_id, post_ids|
177
+ post_ids.each do |post_id|
178
+ db[:comments].insert post_id: post_id, user_id: user_id, text: 'Comment'
179
+ end
180
+ end
181
+
182
+ db[:users].count.must_equal 3
183
+ db[:categories].count.must_equal 3
184
+ db[:posts].count.must_equal 9
185
+ db[:categories_posts].count.must_equal 9
186
+ db[:comments].count.must_equal 9
187
+ end
188
+
189
+ it 'Self relations' do
190
+ db[:posts].where(id: 1).count.must_equal 1
191
+ db[:categories_posts].where(post_id: 1).count.must_equal 1
192
+ db[:comments].where(post_id: 1).count.must_equal 1
193
+
194
+ posts.delete_cascade 1
195
+
196
+ db[:posts].where(id: 1).count.must_equal 0
197
+ db[:categories_posts].where(post_id: 1).count.must_equal 0
198
+ db[:comments].where(post_id: 1).count.must_equal 0
199
+
200
+ db[:users].count.must_equal 3
201
+ db[:categories].count.must_equal 3
202
+ db[:posts].count.must_equal 8
203
+ db[:categories_posts].count.must_equal 8
204
+ db[:comments].count.must_equal 8
205
+ end
206
+
207
+ it 'Deep relations' do
208
+ db[:users].where(id: 1).count.must_equal 1
209
+ db[:comments].where(user_id: 1).count.must_equal 3
210
+ db[:posts].where(user_id: 1).count.must_equal 3
211
+ db[:comments].join(:posts, id: :post_id).where(posts__user_id: 1).count.must_equal 3
212
+ db[:categories_posts].join(:posts, id: :post_id).where(posts__user_id: 1).count.must_equal 3
213
+
214
+ users.delete_cascade 1
215
+
216
+ db[:users].where(id: 1).count.must_equal 0
217
+ db[:comments].where(user_id: 1).count.must_equal 0
218
+ db[:posts].where(user_id: 1).count.must_equal 0
219
+ db[:comments].join(:posts, id: :post_id).where(posts__user_id: 1).count.must_equal 0
220
+ db[:categories_posts].join(:posts, id: :post_id).where(posts__user_id: 1).count.must_equal 0
221
+
222
+ db[:users].count.must_equal 2
223
+ db[:categories].count.must_equal 3
224
+ db[:posts].count.must_equal 6
225
+ db[:categories_posts].count.must_equal 6
226
+ db[:comments].count.must_equal 3
227
+ end
228
+
229
+ end
230
+
231
+ end
232
+
233
+ describe 'Queries' do
234
+
235
+ it 'Find' do
236
+ id = db[:users].insert name: 'User 1'
237
+
238
+ users.find(id).must_equal User.new(id: id, name: 'User 1')
239
+ end
240
+
241
+ it 'Find graph' do
242
+ user_id = db[:users].insert name: 'User 1'
243
+ db[:posts].insert user_id: user_id, title: 'Post 1', body: '...'
244
+
245
+ users.find_graph(user_id, :posts).must_equal User.new id: user_id, name: 'User 1', posts: posts.all
246
+ end
247
+
248
+ it 'Count' do
249
+ 1.upto(10) { |i| db[:users].insert name: "User #{i}" }
250
+
251
+ users.count.must_equal 10
252
+ end
253
+
254
+ it 'All' do
255
+ id = db[:users].insert name: 'User 1'
256
+
257
+ users.all.must_equal [User.new(id: id, name: 'User 1')]
258
+ end
259
+
260
+ it 'First' do
261
+ 1.upto(10) { |i| db[:users].insert name: "User #{i}" }
262
+
263
+ users.first.must_equal User.new(id: 1, name: 'User 1')
264
+ end
265
+
266
+ it 'Exists' do
267
+ 1.upto(10) { |i| db[:users].insert name: "User #{i}" }
268
+
269
+ users.exists?(id: 1).must_equal true
270
+ users.exists?(id: 0).must_equal false
271
+
272
+ users.exists? { where id: 1 }.must_equal true
273
+ users.exists? { where id: 0 }.must_equal false
274
+ end
275
+
276
+ it 'Detect' do
277
+ 1.upto(10) { |i| db[:users].insert name: "User #{i}" }
278
+
279
+ users.detect(id: 1).must_equal User.new(id: 1, name: 'User 1')
280
+ users.detect(id: 0).must_equal nil
281
+
282
+ users.detect { where id: 1 }.must_equal User.new(id: 1, name: 'User 1')
283
+ users.detect { where id: 0 }.must_equal nil
284
+ end
285
+
286
+ it 'Chained query' do
287
+ 1.upto(10) { |i| db[:users].insert name: "User #{i}" }
288
+
289
+ models = users.where(id: [1,2]).reverse_order(:id).all
290
+
291
+ models.must_equal [2,1].map { |i| User.new(id: i, name: "User #{i}") }
292
+ end
293
+
294
+ it 'Chain dataset as query' do
295
+ 1.upto(2) { |i| db[:users].insert name: "User #{i}" }
296
+ 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...' }
297
+ 1.upto(2) { |i| db[:comments].insert post_id: i, user_id: 2, text: 'Comment' }
298
+
299
+ models = posts.commented_by(2).all
300
+ models.must_equal [1,2].map { |i| Post.new(id: i, user_id: 1, title: "Post #{i}", body: '...') }
301
+ end
302
+
303
+ it 'Custom query' do
304
+ 1.upto(2) { |i| db[:users].insert name: "User #{i}" }
305
+ 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...' }
306
+ 1.upto(2) { |i| db[:comments].insert post_id: i, user_id: 2, text: 'Comment' }
307
+
308
+ models = comments.posts_commented_by(2)
309
+ models.must_equal [1,2].map { |i| Post.new(id: i, user_id: 1, title: "Post #{i}", body: '...') }
310
+ end
311
+
312
+ describe 'Named queries' do
313
+
314
+ before do
315
+ 1.upto(2) { |i| db[:users].insert name: "User #{i}" }
316
+ 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...' }
317
+ 4.upto(5) { |i| db[:posts].insert user_id: 2, title: "Post #{i}", body: '...' }
318
+ end
319
+
320
+ it 'Global' do
321
+ result_1 = posts.created_by(1)
322
+ result_1.map(&:id).must_equal [1,2,3]
323
+
324
+ result_2 = posts.created_by(2)
325
+ result_2.map(&:id).must_equal [4,5]
326
+ end
327
+
328
+ it 'Chained' do
329
+ result = posts.created_by(2).entitled('Post 4')
330
+ result.map(&:id).must_equal [4]
331
+ end
332
+
333
+ end
334
+
335
+ it 'Graph' do
336
+ 1.upto(3) do |i|
337
+ db[:users].insert name: "User #{i}"
338
+ db[:categories].insert name: "Category #{i}"
339
+ db[:posts].insert user_id: i, title: "Post #{i}", body: '...'
340
+ db[:categories_posts].insert post_id: i, category_id: i
341
+ end
342
+
343
+ db[:posts].map(:id).each do |post_id|
344
+ db[:users].map(:id).each do |user_id|
345
+ db[:comments].insert post_id: post_id, user_id: user_id, text: 'Comment'
346
+ end
347
+ end
348
+
349
+ posts_graph = posts.where(id: 1).graph(:user, :categories, 'comments.user.posts.categories').all
350
+
351
+ posts_graph.count.must_equal 1
352
+
353
+ posts_graph[0].user.must_equal users.find(1)
354
+
355
+ posts_graph[0].categories.must_equal [categories.find(1)]
356
+
357
+ posts_graph[0].comments.count.must_equal 3
358
+ posts_graph[0].comments.each_with_index do |comment, index|
359
+ i = index + 1
360
+
361
+ comment.post_id.must_equal 1
362
+ comment.user_id.must_equal i
363
+
364
+ comment.user.id.must_equal i
365
+ comment.user.name.must_equal "User #{i}"
366
+
367
+ comment.user.posts.count.must_equal 1
368
+ comment.user.posts[0].id.must_equal i
369
+ comment.user.posts[0].title.must_equal "Post #{i}"
370
+ comment.user.posts[0].user_id.must_equal i
371
+
372
+ comment.user.posts[0].categories.count.must_equal 1
373
+ comment.user.posts[0].categories[0].id.must_equal i
374
+ comment.user.posts[0].categories[0].name.must_equal "Category #{i}"
375
+ end
376
+ end
377
+
378
+ end
379
+
380
+ describe 'Schemas' do
381
+
382
+ let :stub_db do
383
+ stubs = Proc.new do |sql|
384
+ case sql
385
+
386
+ when 'SELECT * FROM custom_schema.users',
387
+ 'SELECT * FROM custom_schema.users WHERE (id IN (2, 1))'
388
+ [
389
+ {id: 1},
390
+ {id: 2}
391
+ ]
392
+
393
+ when 'SELECT * FROM custom_schema.posts',
394
+ 'SELECT * FROM custom_schema.posts WHERE (user_id IN (1, 2))'
395
+ [
396
+ {id: 3, user_id: 1},
397
+ {id: 4, user_id: 2}
398
+ ]
399
+
400
+ when 'SELECT * FROM custom_schema.comments WHERE (post_id IN (3, 4))'
401
+ [
402
+ {id: 5, user_id: 2, post_id: 3},
403
+ {id: 6, user_id: 1, post_id: 3},
404
+ {id: 7, user_id: 1, post_id: 4},
405
+ {id: 8, user_id: 2, post_id: 4}
406
+ ]
407
+
408
+ else
409
+ nil
410
+ end
411
+ end
412
+
413
+ Sequel.mock(fetch: stubs, autoid: 1).tap do |mock|
414
+ get_schema_block = ->(table_name) { db.schema table_name }
415
+ mock.define_singleton_method(:schema_parse_table) do |table_name, opts|
416
+ get_schema_block.call table_name
417
+ end
418
+ end
419
+ end
420
+
421
+ let(:stub_users) { Users.new stub_db, :custom_schema }
422
+ let(:stub_posts) { Posts.new stub_db, :custom_schema }
423
+ let(:stub_comments) { Comments.new stub_db, :custom_schema }
424
+
425
+ it 'Insert' do
426
+ stub_users.insert name: 'User 1'
427
+ stub_db.sqls.must_equal [
428
+ 'BEGIN',
429
+ "INSERT INTO custom_schema.users (name) VALUES ('User 1')",
430
+ 'COMMIT'
431
+ ]
432
+ end
433
+
434
+ it 'Insert with many to many relation' do
435
+ stub_posts.insert user_id: 1, title: 'Post 1', body: '...', categories: [2,3]
436
+ stub_db.sqls.must_equal [
437
+ 'BEGIN',
438
+ "INSERT INTO custom_schema.posts (user_id, title, body) VALUES (1, 'Post 1', '...')",
439
+ 'DELETE FROM custom_schema.categories_posts WHERE (post_id IN (1))',
440
+ 'INSERT INTO custom_schema.categories_posts (post_id, category_id) VALUES (1, 2)',
441
+ 'INSERT INTO custom_schema.categories_posts (post_id, category_id) VALUES (1, 3)',
442
+ 'COMMIT'
443
+ ]
444
+ end
445
+
446
+ it 'Update' do
447
+ stub_users.update 1, name: 'Updated name'
448
+ stub_db.sqls.must_equal [
449
+ 'BEGIN',
450
+ "UPDATE custom_schema.users SET name = 'Updated name' WHERE (id = 1)",
451
+ 'COMMIT'
452
+ ]
453
+ end
454
+
455
+ it 'Delete' do
456
+ stub_users.delete 1
457
+ stub_db.sqls.must_equal ['DELETE FROM custom_schema.users WHERE (id = 1)']
458
+ end
459
+
460
+ it 'Chained query' do
461
+ stub_users.where(id: [1,2]).limit(1).order(:name).all
462
+ stub_db.sqls.must_equal ['SELECT * FROM custom_schema.users WHERE (id IN (1, 2)) ORDER BY name LIMIT 1']
463
+ end
464
+
465
+ it 'Graph' do
466
+ stub_posts.graph(:user, :categories, 'comments.user.posts.categories').all
467
+ stub_db.sqls.must_equal [
468
+ 'SELECT * FROM custom_schema.posts',
469
+ 'SELECT * FROM custom_schema.users WHERE (id IN (1, 2))',
470
+ 'SELECT * FROM custom_schema.categories INNER JOIN custom_schema.categories_posts ON (custom_schema.categories_posts.category_id = custom_schema.categories.id) WHERE (custom_schema.categories_posts.post_id IN (3, 4))',
471
+ 'SELECT * FROM custom_schema.comments WHERE (post_id IN (3, 4))',
472
+ 'SELECT * FROM custom_schema.users WHERE (id IN (2, 1))',
473
+ 'SELECT * FROM custom_schema.posts WHERE (user_id IN (1, 2))',
474
+ 'SELECT * FROM custom_schema.categories INNER JOIN custom_schema.categories_posts ON (custom_schema.categories_posts.category_id = custom_schema.categories.id) WHERE (custom_schema.categories_posts.post_id IN (3, 4))'
475
+ ]
476
+ end
477
+
478
+ it 'Named query' do
479
+ stub_posts.commented_by(1).all
480
+ stub_db.sqls.must_equal [
481
+ 'SELECT DISTINCT custom_schema.posts.* FROM custom_schema.posts INNER JOIN custom_schema.comments ON (custom_schema.comments.post_id = custom_schema.posts.id) WHERE (custom_schema.comments.user_id = 1)'
482
+ ]
483
+ end
484
+
485
+ it 'Custom query' do
486
+ stub_comments.posts_commented_by(2)
487
+ stub_db.sqls.must_equal [
488
+ 'SELECT custom_schema.posts.* FROM custom_schema.comments INNER JOIN custom_schema.posts ON (custom_schema.posts.id = custom_schema.comments.post_id) WHERE (comments.user_id = 2)'
489
+ ]
490
+ end
491
+
492
+ end
493
+
494
+ end
@@ -0,0 +1,5 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
5
+ SimpleCov.start
@@ -0,0 +1,113 @@
1
+ require 'coverage_helper'
2
+ require 'rasti-db'
3
+ require 'minitest/autorun'
4
+ require 'minitest/colorin'
5
+ require 'pry-nav'
6
+ require 'logger'
7
+ require 'sequel/extensions/pg_hstore'
8
+ require 'sequel/extensions/pg_array'
9
+ require 'sequel/extensions/pg_json'
10
+
11
+ User = Rasti::DB::Model[:id, :name, :posts, :comments]
12
+ Post = Rasti::DB::Model[:id, :title, :body, :user_id, :user, :comments, :categories]
13
+ Comment = Rasti::DB::Model[:id, :text, :user_id, :user, :post_id, :post]
14
+ Category = Rasti::DB::Model[:id, :name, :posts]
15
+
16
+
17
+ class Users < Rasti::DB::Collection
18
+ one_to_many :posts
19
+ one_to_many :comments
20
+ end
21
+
22
+ class Posts < Rasti::DB::Collection
23
+ many_to_one :user
24
+ many_to_many :categories
25
+ one_to_many :comments
26
+
27
+ query :created_by, ->(user_id) { where user_id: user_id }
28
+
29
+ query :entitled do |title|
30
+ where title: title
31
+ end
32
+
33
+ query :commented_by do |user_id|
34
+ chainable do
35
+ dataset.join(with_schema(:comments), post_id: :id)
36
+ .where(with_schema(:comments, :user_id) => user_id)
37
+ .select_all(with_schema(:posts))
38
+ .distinct
39
+ end
40
+ end
41
+ end
42
+
43
+ class Comments < Rasti::DB::Collection
44
+ many_to_one :user
45
+ many_to_one :post
46
+
47
+ def posts_commented_by(user_id)
48
+ dataset.where(comments__user_id: user_id)
49
+ .join(with_schema(:posts), id: :post_id)
50
+ .select_all(with_schema(:posts))
51
+ .map { |row| Post.new row }
52
+ end
53
+ end
54
+
55
+ class Categories < Rasti::DB::Collection
56
+ many_to_many :posts
57
+ end
58
+
59
+
60
+ Rasti::DB::TypeConverter::CONVERTIONS[:sqlite] = {
61
+ /integer/ => ->(value, match) { value.to_i }
62
+ }
63
+
64
+
65
+ class Minitest::Spec
66
+
67
+ DB_DRIVER = (RUBY_ENGINE == 'jruby') ? 'jdbc:sqlite::memory:' : {adapter: :sqlite}
68
+
69
+ let(:users) { Users.new db }
70
+
71
+ let(:posts) { Posts.new db }
72
+
73
+ let(:comments) { Comments.new db }
74
+
75
+ let(:categories) { Categories.new db }
76
+
77
+ let :db do
78
+ db = Sequel.connect DB_DRIVER
79
+
80
+ db.create_table :users do
81
+ primary_key :id
82
+ String :name, null: false, unique: true
83
+ end
84
+
85
+ db.create_table :posts do
86
+ primary_key :id
87
+ String :title, null: false, unique: true
88
+ String :body, null: false
89
+ foreign_key :user_id, :users, null: false, index: true
90
+ end
91
+
92
+ db.create_table :comments do
93
+ primary_key :id
94
+ String :text, null: false
95
+ foreign_key :user_id, :users, null: false, index: true
96
+ foreign_key :post_id, :posts, null: false, index: true
97
+ end
98
+
99
+ db.create_table :categories do
100
+ primary_key :id
101
+ String :name, null: false, unique: true
102
+ end
103
+
104
+ db.create_table :categories_posts do
105
+ foreign_key :category_id, :categories, null: false, index: true
106
+ foreign_key :post_id, :posts, null: false, index: true
107
+ primary_key [:category_id, :post_id]
108
+ end
109
+
110
+ db
111
+ end
112
+
113
+ end
@@ -0,0 +1,82 @@
1
+ require 'minitest_helper'
2
+
3
+ describe 'Model' do
4
+
5
+ describe 'Attribues' do
6
+
7
+ it 'Valid definition' do
8
+ model = Rasti::DB::Model[:id, :name]
9
+ model.attributes.must_equal [:id, :name]
10
+ end
11
+
12
+ it 'Invalid definition' do
13
+ error = proc { model = Rasti::DB::Model[:id, :name, :name] }.must_raise ArgumentError
14
+ error.message.must_equal 'Attribute name already exists'
15
+ end
16
+
17
+ it 'Accessors' do
18
+ post = Post.new id: 1, title: 'Title'
19
+
20
+ post.id.must_equal 1
21
+ post.title.must_equal 'Title'
22
+
23
+ [:body, :user, :comments].each do |attribute|
24
+ error = proc { post.send attribute }.must_raise Rasti::DB::Model::UninitializedAttributeError
25
+ error.message.must_equal "Uninitialized attribute #{attribute}"
26
+ end
27
+
28
+ proc { post.invalid_method }.must_raise NoMethodError
29
+ end
30
+
31
+ end
32
+
33
+
34
+ it 'Inheritance' do
35
+ subclass = Class.new(User) do
36
+ attribute :additional_attribute
37
+ end
38
+
39
+ subclass.attributes.must_equal (User.attributes + [:additional_attribute])
40
+ end
41
+
42
+ describe 'To String' do
43
+
44
+ it 'Class' do
45
+ User.to_s.must_equal 'User[id, name, posts, comments]'
46
+ end
47
+
48
+ it 'Instance' do
49
+ user = User.new id: 1, name: 'User 1'
50
+ user.to_s.must_equal '#<User[id: 1, name: "User 1"]>'
51
+ end
52
+
53
+ end
54
+
55
+ it 'To Hash' do
56
+ post = Post.new id: 2,
57
+ title: 'Title',
58
+ body: 'body',
59
+ user_id: 1,
60
+ user: User.new(id: 1, name: 'User 1'),
61
+ comments: [Comment.new(id: 4, text: 'comment text', user_id: 5)]
62
+
63
+ post.to_h.must_equal id: 2,
64
+ title: 'Title',
65
+ body: 'body',
66
+ user_id: 1,
67
+ user: {id: 1, name: 'User 1'},
68
+ comments: [{id: 4, text: 'comment text', user_id: 5}]
69
+ end
70
+
71
+ it 'Equality' do
72
+ assert User.new(id: 1, name: 'User 1') == User.new(id: 1, name: 'User 1')
73
+ refute User.new(id: 1, name: 'User 1') == User.new(id: 2, name: 'User 2')
74
+
75
+ assert User.new(id: 1, name: 'User 1').eql? User.new(id: 1, name: 'User 1')
76
+ refute User.new(id: 1, name: 'User 1').eql? User.new(id: 2, name: 'User 2')
77
+
78
+ assert_equal User.new(id: 1, name: 'User 1').hash, User.new(id: 1, name: 'User 1').hash
79
+ refute_equal User.new(id: 1, name: 'User 1').hash, User.new(id: 2, name: 'User 2').hash
80
+ end
81
+
82
+ end