toystore 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/.gitignore +1 -2
  2. data/Changelog.md +9 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +71 -0
  5. data/Guardfile +15 -0
  6. data/README.md +28 -0
  7. data/examples/attributes_abbreviation.rb +1 -2
  8. data/examples/attributes_virtual.rb +1 -2
  9. data/examples/identity_map.rb +7 -12
  10. data/examples/memcached.rb +1 -1
  11. data/examples/memory.rb +1 -1
  12. data/examples/mongo.rb +1 -1
  13. data/examples/redis.rb +1 -1
  14. data/examples/riak.rb +1 -1
  15. data/lib/toy.rb +40 -39
  16. data/lib/toy/attribute.rb +1 -6
  17. data/lib/toy/attributes.rb +61 -90
  18. data/lib/toy/caching.rb +11 -13
  19. data/lib/toy/callbacks.rb +12 -31
  20. data/lib/toy/cloneable.rb +20 -0
  21. data/lib/toy/collection.rb +8 -7
  22. data/lib/toy/dirty.rb +17 -36
  23. data/lib/toy/dirty_store.rb +32 -0
  24. data/lib/toy/equality.rb +2 -0
  25. data/lib/toy/extensions/boolean.rb +22 -18
  26. data/lib/toy/identity_map.rb +39 -62
  27. data/lib/toy/list.rb +23 -22
  28. data/lib/toy/logger.rb +2 -17
  29. data/lib/toy/mass_assignment_security.rb +3 -5
  30. data/lib/toy/middleware/identity_map.rb +23 -4
  31. data/lib/toy/object.rb +16 -0
  32. data/lib/toy/persistence.rb +72 -62
  33. data/lib/toy/proxies/list.rb +19 -18
  34. data/lib/toy/proxies/proxy.rb +7 -6
  35. data/lib/toy/querying.rb +2 -4
  36. data/lib/toy/reference.rb +28 -26
  37. data/lib/toy/reloadable.rb +17 -0
  38. data/lib/toy/serialization.rb +25 -25
  39. data/lib/toy/store.rb +3 -11
  40. data/lib/toy/validations.rb +9 -28
  41. data/lib/toy/version.rb +1 -1
  42. data/perf/reads.rb +7 -9
  43. data/perf/writes.rb +6 -8
  44. data/spec/helper.rb +3 -1
  45. data/spec/support/constants.rb +1 -4
  46. data/spec/support/identity_map_matcher.rb +5 -5
  47. data/spec/support/objects.rb +38 -0
  48. data/spec/toy/attribute_spec.rb +1 -1
  49. data/spec/toy/attributes_spec.rb +1 -153
  50. data/spec/toy/callbacks_spec.rb +1 -45
  51. data/spec/toy/cloneable_spec.rb +47 -0
  52. data/spec/toy/dirty_spec.rb +12 -44
  53. data/spec/toy/dirty_store_spec.rb +47 -0
  54. data/spec/toy/equality_spec.rb +5 -19
  55. data/spec/toy/extensions/boolean_spec.rb +2 -0
  56. data/spec/toy/identity/uuid_key_factory_spec.rb +2 -2
  57. data/spec/toy/identity_map_spec.rb +45 -37
  58. data/spec/toy/identity_spec.rb +1 -1
  59. data/spec/toy/inspect_spec.rb +1 -1
  60. data/spec/toy/lists_spec.rb +20 -5
  61. data/spec/toy/logger_spec.rb +1 -29
  62. data/spec/toy/mass_assignment_security_spec.rb +16 -5
  63. data/spec/toy/middleware/identity_map_spec.rb +68 -2
  64. data/spec/toy/persistence_spec.rb +88 -30
  65. data/spec/toy/reference_spec.rb +0 -1
  66. data/spec/toy/references_spec.rb +20 -0
  67. data/spec/toy/reloadable_spec.rb +81 -0
  68. data/spec/toy/serialization_spec.rb +1 -110
  69. data/spec/toy/validations_spec.rb +0 -21
  70. data/spec/toy_spec.rb +4 -5
  71. data/test/lint_test.rb +1 -1
  72. metadata +21 -26
  73. data/.autotest +0 -11
  74. data/LOGGING.rdoc +0 -12
  75. data/README.rdoc +0 -27
  76. data/examples/models.rb +0 -51
  77. data/lib/toy/dolly.rb +0 -30
  78. data/lib/toy/embedded_list.rb +0 -45
  79. data/lib/toy/embedded_lists.rb +0 -68
  80. data/lib/toy/index.rb +0 -74
  81. data/lib/toy/indices.rb +0 -56
  82. data/lib/toy/proxies/embedded_list.rb +0 -79
  83. data/spec/toy/dolly_spec.rb +0 -76
  84. data/spec/toy/embedded_list_spec.rb +0 -607
  85. data/spec/toy/embedded_lists_spec.rb +0 -172
  86. data/spec/toy/index_spec.rb +0 -230
  87. data/spec/toy/indices_spec.rb +0 -141
  88. data/specs.watchr +0 -52
@@ -1,76 +0,0 @@
1
- require 'helper'
2
-
3
- describe Toy::Dolly do
4
- uses_constants('User', 'Game', 'Move')
5
-
6
- before do
7
- Game.embedded_list(:moves)
8
- User.attribute(:name, String)
9
- User.attribute(:skills, Array)
10
- User.list(:games)
11
-
12
- @move = Move.new
13
- @game = Game.create(:moves => [@move])
14
- @user = User.create({
15
- :name => 'John',
16
- :skills => ['looking awesome', 'growing beards'],
17
- :games => [@game],
18
- })
19
- end
20
- let(:move) { @move }
21
- let(:game) { @game }
22
- let(:user) { @user }
23
-
24
- describe "#clone" do
25
- it "returns new instance" do
26
- user.clone.should be_new_record
27
- end
28
-
29
- it "has no changes" do
30
- user.clone.should_not be_changed
31
- end
32
-
33
- it "is never destroyed" do
34
- user.destroy
35
- user.clone.should_not be_destroyed
36
- end
37
-
38
- it "clones the @attributes hash" do
39
- user.clone.instance_variable_get("@attributes").should_not equal(user.instance_variable_get("@attributes"))
40
- end
41
-
42
- it "copies the attributes" do
43
- user.clone.tap do |clone|
44
- clone.name.should == user.name
45
- clone.skills.should == user.skills
46
- end
47
- end
48
-
49
- it "clones duplicable attributes" do
50
- user.clone.skills.should_not equal(user.skills)
51
- end
52
-
53
- it "regenerates id" do
54
- user.clone.tap do |clone|
55
- clone.id.should_not be_nil
56
- clone.id.should_not == user.id
57
- end
58
- end
59
-
60
- it "clones list id attributes" do
61
- user.clone.game_ids.should_not equal(user.game_ids)
62
- end
63
-
64
- it "clones the list" do
65
- user.clone.games.should_not equal(user.games)
66
- end
67
-
68
- it "clones embedded list objects" do
69
- game.clone.moves.first.should_not equal(game.moves.first)
70
- end
71
-
72
- it "regenerates ids for embedded list objects" do
73
- game.clone.moves.first.id.should_not == game.moves.first.id
74
- end
75
- end
76
- end
@@ -1,607 +0,0 @@
1
- require 'helper'
2
-
3
- describe Toy::List do
4
- uses_constants('Game', 'Move')
5
-
6
- before do
7
- @list = Game.embedded_list(:moves)
8
- end
9
-
10
- let(:list) { @list }
11
-
12
- it "has model" do
13
- list.model.should == Game
14
- end
15
-
16
- it "has name" do
17
- list.name.should == :moves
18
- end
19
-
20
- it "has type" do
21
- list.type.should == Move
22
- end
23
-
24
- it "has instance_variable" do
25
- list.instance_variable.should == :@_moves
26
- end
27
-
28
- it "adds list to model" do
29
- Game.embedded_lists.keys.should include(:moves)
30
- end
31
-
32
- it "adds reader method" do
33
- Game.new.should respond_to(:moves)
34
- end
35
-
36
- it "adds writer method" do
37
- Game.new.should respond_to(:moves=)
38
- end
39
-
40
- describe "#eql?" do
41
- it "returns true if same class, model, and name" do
42
- list.should eql(list)
43
- end
44
-
45
- it "returns false if not same class" do
46
- list.should_not eql({})
47
- end
48
-
49
- it "returns false if not same model" do
50
- list.should_not eql(Toy::List.new(Move, :moves))
51
- end
52
-
53
- it "returns false if not the same name" do
54
- list.should_not eql(Toy::List.new(Game, :recent_moves))
55
- end
56
- end
57
-
58
- describe "setting list type" do
59
- before do
60
- @list = Game.embedded_list(:recent_moves, Move)
61
- end
62
- let(:list) { @list }
63
-
64
- it "uses type provided instead of inferring from name" do
65
- list.type.should be(Move)
66
- end
67
-
68
- it "works properly when reading and writing" do
69
- game = Game.create
70
- move = Move.create
71
- game.recent_moves = [move]
72
- game.recent_moves.should == [move]
73
- end
74
- end
75
-
76
- describe "list reader" do
77
- before do
78
- Move.attribute(:index, Integer)
79
- @game = Game.create(:move_attributes => [{:index => 0}, {:index => 1}])
80
- end
81
-
82
- it "returns instances" do
83
- @game.moves.each do |move|
84
- move.should be_instance_of(Move)
85
- end
86
- @game.moves[0].id.should_not be_nil
87
- @game.moves[1].id.should_not be_nil
88
- @game.moves[0].index.should == 0
89
- @game.moves[1].index.should == 1
90
- end
91
-
92
- it "sets reference to parent for each instance" do
93
- @game.moves.each do |move|
94
- move.parent_reference.should == @game
95
- end
96
- end
97
- end
98
-
99
- describe "list writer" do
100
- before do
101
- @move1 = Move.new
102
- @move2 = Move.new
103
- @game = Game.create(:moves => [@move2])
104
- end
105
-
106
- it "set attribute" do
107
- @game.move_attributes.should == [@move2.attributes]
108
- end
109
-
110
- it "unmemoizes reader" do
111
- @game.moves.should == [@move2]
112
- @game.moves = [@move1]
113
- @game.moves.should == [@move1]
114
- end
115
-
116
- it "sets reference to parent for each instance" do
117
- @game.moves.each do |move|
118
- move.parent_reference.should == @game
119
- end
120
- end
121
- end
122
-
123
- describe "list attribute writer" do
124
- before do
125
- Move.attribute(:index, Integer)
126
- @game = Game.new('move_attributes' => [
127
- {'index' => '1'}
128
- ])
129
- end
130
-
131
- it "typecasts hash values correctly" do
132
- @game.move_attributes.should == [
133
- {'id' => @game.moves[0].id, 'index' => 1}
134
- ]
135
- end
136
-
137
- it "accepts hash of hashes" do
138
- game = Game.new('move_attributes' => {
139
- '0' => {'index' => 1},
140
- '1' => {'index' => 2},
141
- '2' => {'index' => 3},
142
- })
143
- game.move_attributes.should == [
144
- {'id' => game.moves[0].id, 'index' => 1},
145
- {'id' => game.moves[1].id, 'index' => 2},
146
- {'id' => game.moves[2].id, 'index' => 3},
147
- ]
148
- end
149
-
150
- it "sets ids if present" do
151
- game = Game.new('move_attributes' => [
152
- {'id' => 'foo', 'index' => '1'}
153
- ])
154
- game.move_attributes.should == [
155
- {'id' => 'foo', 'index' => 1},
156
- ]
157
- end
158
- end
159
-
160
- describe "list#push" do
161
- before do
162
- @move = Move.new
163
- @game = Game.new
164
- @game.moves.push(@move)
165
- end
166
-
167
- it "raises error if wrong type assigned" do
168
- lambda {
169
- @game.moves.push(Game.new)
170
- }.should raise_error(ArgumentError, "Move expected, but was Game")
171
- end
172
-
173
- it "sets reference to parent" do
174
- # right now pushing a move adds a different instance to the proxy
175
- # so i'm checking that it adds reference to both
176
- @game.moves.each do |move|
177
- move.parent_reference.should == @game
178
- end
179
- @move.parent_reference.should == @game
180
- end
181
-
182
- it "instances should not be persisted" do
183
- @game.moves.each do |move|
184
- move.should_not be_persisted
185
- end
186
- end
187
-
188
- it "marks instances as persisted when parent saved" do
189
- @game.save
190
- @game.moves.each do |move|
191
- move.should be_persisted
192
- end
193
- end
194
-
195
- it "should save list" do
196
- moves = @game.moves.target
197
- @game.save
198
- @game.reload
199
- @game.moves.should == moves
200
- end
201
-
202
- it "should keep existing instances as persisted when adding a new instance" do
203
- @game.save
204
- @game.moves.push(Move.new)
205
- @game.moves.first.should be_persisted
206
- @game.moves.last.should_not be_persisted
207
- end
208
-
209
- it "marks instances as persisted when updated" do
210
- @game.save
211
- game = @game.reload
212
- move = Move.new
213
- game.moves.push(move)
214
- move.should_not be_persisted
215
- game.save
216
- game.moves.each do |move|
217
- move.should be_persisted
218
- end
219
- # move.should be_persisted
220
- end
221
- end
222
-
223
- describe "list#<<" do
224
- before do
225
- @move = Move.new
226
- @game = Game.new
227
- @game.moves << @move
228
- end
229
-
230
- it "raises error if wrong type assigned" do
231
- lambda {
232
- @game.moves << Game.new
233
- }.should raise_error(ArgumentError, "Move expected, but was Game")
234
- end
235
-
236
- it "sets reference to parent" do
237
- # right now pushing a move adds a different instance to the proxy
238
- # so i'm checking that it adds reference to both
239
- @game.moves.each do |move|
240
- move.parent_reference.should == @game
241
- end
242
- @move.parent_reference.should == @game
243
- end
244
-
245
- it "instances should not be persisted" do
246
- @game.moves.each do |move|
247
- move.should_not be_persisted
248
- end
249
- end
250
-
251
- it "marks instances as persisted when parent saved" do
252
- @game.save
253
- @game.moves.each do |move|
254
- move.should be_persisted
255
- end
256
- end
257
- end
258
-
259
- describe "list#concat" do
260
- before do
261
- @move1 = Move.new
262
- @move2 = Move.new
263
- @game = Game.new
264
- @game.moves.concat(@move1, @move2)
265
- end
266
-
267
- it "raises error if wrong type assigned" do
268
- lambda {
269
- @game.moves.concat(Game.new, Move.new)
270
- }.should raise_error(ArgumentError, "Move expected, but was Game")
271
- end
272
-
273
- it "sets reference to parent" do
274
- # right now pushing a move adds a different instance to the proxy
275
- # so i'm checking that it adds reference to both
276
- @game.moves.each do |move|
277
- move.parent_reference.should == @game
278
- end
279
- @move1.parent_reference.should == @game
280
- @move2.parent_reference.should == @game
281
- end
282
-
283
- it "instances should not be persisted" do
284
- @game.moves.each do |move|
285
- move.should_not be_persisted
286
- end
287
- end
288
-
289
- it "marks instances as persisted when parent saved" do
290
- @game.save
291
- @game.moves.each do |move|
292
- move.should be_persisted
293
- end
294
- end
295
- end
296
-
297
- describe "list#concat (with array)" do
298
- before do
299
- @move1 = Move.new
300
- @move2 = Move.new
301
- @game = Game.create
302
- @game.moves.concat([@move1, @move2])
303
- end
304
-
305
- it "raises error if wrong type assigned" do
306
- lambda {
307
- @game.moves.concat([Game.new, Move.new])
308
- }.should raise_error(ArgumentError, "Move expected, but was Game")
309
- end
310
-
311
- it "sets reference to parent" do
312
- # right now pushing a move adds a different instance to the proxy
313
- # so i'm checking that it adds reference to both
314
- @game.moves.each do |move|
315
- move.parent_reference.should == @game
316
- end
317
- @move1.parent_reference.should == @game
318
- @move2.parent_reference.should == @game
319
- end
320
-
321
- it "instances should not be persisted" do
322
- @game.moves.each do |move|
323
- move.should_not be_persisted
324
- end
325
- end
326
-
327
- it "marks instances as persisted when parent saved" do
328
- @game.save
329
- @game.moves.each do |move|
330
- move.should be_persisted
331
- end
332
- end
333
- end
334
-
335
- shared_examples_for("embedded_list#create") do
336
- it "creates instance" do
337
- @move.should be_persisted
338
- end
339
-
340
- it "assigns reference to parent" do
341
- @move.parent_reference.should == @game
342
- end
343
-
344
- it "assigns id" do
345
- @move.id.should_not be_nil
346
- end
347
-
348
- it "adds instance to reader" do
349
- @game.moves.should == [@move]
350
- end
351
-
352
- it "marks instance as persisted" do
353
- @move.should be_persisted
354
- end
355
- end
356
-
357
- describe "list#create" do
358
- before do
359
- @game = Game.create
360
- @move = @game.moves.create
361
- end
362
-
363
- it_should_behave_like "embedded_list#create"
364
- end
365
-
366
- describe "list#create (with attributes)" do
367
- before do
368
- Move.attribute(:move_index, Integer)
369
- @game = Game.create
370
- @move = @game.moves.create(:move_index => 0)
371
- end
372
-
373
- it_should_behave_like "embedded_list#create"
374
-
375
- it "sets attributes on instance" do
376
- @move.move_index.should == 0
377
- end
378
- end
379
-
380
- describe "list#create (invalid)" do
381
- before do
382
- @game = Game.create
383
- @game.moves.should_not_receive(:push)
384
- @game.moves.should_not_receive(:reset)
385
- @game.should_not_receive(:reload)
386
- @game.should_not_receive(:save)
387
-
388
- Move.attribute(:move_index, Integer)
389
- Move.validates_presence_of(:move_index)
390
-
391
- @move = @game.moves.create
392
- end
393
-
394
- it "returns instance" do
395
- @move.should be_instance_of(Move)
396
- end
397
-
398
- it "is not persisted" do
399
- @move.should_not be_persisted
400
- end
401
-
402
- it "assigns reference to parent" do
403
- @move.parent_reference.should == @game
404
- end
405
- end
406
-
407
- describe "list#create (valid with invalid root that validates embedded)" do
408
- before do
409
- Game.attribute(:user_id, String)
410
- Game.validates_presence_of(:user_id)
411
-
412
- @game = Game.new
413
- @move = @game.moves.create
414
- end
415
-
416
- it "is not persisted" do
417
- @move.should_not be_persisted
418
- end
419
-
420
- it "is persisted when root is valid and saved" do
421
- @game.user_id = '1'
422
- @game.save!
423
- @move.should be_persisted
424
- end
425
- end
426
-
427
- describe "list#destroy" do
428
- before do
429
- Move.attribute(:move_index, Integer)
430
- @game = Game.create
431
- @move1 = @game.moves.create(:move_index => 0)
432
- @move2 = @game.moves.create(:move_index => 1)
433
- end
434
-
435
- it "should take multiple ids" do
436
- @game.moves.destroy(@move1.id, @move2.id)
437
- @game.moves.should be_empty
438
- @game.reload
439
- @game.moves.should be_empty
440
- end
441
-
442
- it "should take an array of ids" do
443
- @game.moves.destroy([@move1.id, @move2.id])
444
- @game.moves.should be_empty
445
- @game.reload
446
- @game.moves.should be_empty
447
- end
448
-
449
- it "should take a block to filter on" do
450
- @game.moves.destroy { |move| move.move_index == 1 }
451
- @game.moves.should == [@move1]
452
- @game.reload
453
- @game.moves.should == [@move1]
454
- end
455
- end
456
-
457
- describe "list#destroy_all" do
458
- before do
459
- Move.attribute(:move_index, Integer)
460
- @game = Game.create
461
- @move1 = @game.moves.create(:move_index => 0)
462
- @move2 = @game.moves.create(:move_index => 1)
463
- end
464
-
465
- it "should destroy all" do
466
- @game.moves.destroy_all
467
- @game.moves.should be_empty
468
- @game.reload
469
- @game.moves.should be_empty
470
- end
471
- end
472
-
473
- describe "list#each" do
474
- before do
475
- @move1 = Move.new
476
- @move2 = Move.new
477
- @game = Game.create(:moves => [@move1, @move2])
478
- end
479
-
480
- it "iterates through each instance" do
481
- moves = []
482
- @game.moves.each do |move|
483
- moves << move
484
- end
485
- moves.should == [@move1, @move2]
486
- end
487
- end
488
-
489
- describe "enumerating" do
490
- before do
491
- Move.attribute(:move_index, Integer)
492
- @move1 = Move.new(:move_index => 0)
493
- @move2 = Move.new(:move_index => 1)
494
- @game = Game.create(:moves => [@move1, @move2])
495
- end
496
-
497
- it "works" do
498
- @game.moves.select { |move| move.move_index > 0 }.should == [@move2]
499
- @game.moves.reject { |move| move.move_index > 0 }.should == [@move1]
500
- end
501
- end
502
-
503
- describe "list#include?" do
504
- before do
505
- @move1 = Move.new
506
- @move2 = Move.new
507
- @game = Game.create(:moves => [@move1])
508
- end
509
-
510
- it "returns true if instance in association" do
511
- @game.moves.should include(@move1)
512
- end
513
-
514
- it "returns false if instance not in association" do
515
- @game.moves.should_not include(@move2)
516
- end
517
-
518
- it "returns false for nil" do
519
- @game.moves.should_not include(nil)
520
- end
521
- end
522
-
523
- describe "list with block" do
524
- before do
525
- Move.attribute(:old, Boolean)
526
- Game.embedded_list(:moves) do
527
- def old
528
- target.select { |move| move.old? }
529
- end
530
- end
531
-
532
- @move_new = Move.create(:old => false)
533
- @move_old = Move.create(:old => true)
534
- @game = Game.create(:moves => [@move_new, @move_old])
535
- end
536
-
537
- it "extends block methods onto proxy" do
538
- @game.moves.respond_to?(:old).should be_true
539
- @game.moves.old.should == [@move_old]
540
- end
541
- end
542
-
543
- describe "list extension with :extensions option" do
544
- before do
545
- old_module = Module.new do
546
- def old
547
- target.select { |m| m.old? }
548
- end
549
- end
550
-
551
- recent_proc = Proc.new do
552
- def recent
553
- target.select { |m| !m.old? }
554
- end
555
- end
556
-
557
- Move.attribute(:old, Boolean)
558
- Game.embedded_list(:moves, :extensions => [old_module, recent_proc])
559
-
560
- @move_new = Move.new(:old => false)
561
- @move_old = Move.new(:old => true)
562
- @game = Game.create(:moves => [@move_new, @move_old])
563
- end
564
-
565
- it "extends modules" do
566
- @game.moves.respond_to?(:old).should be_true
567
- @game.moves.old.should == [@move_old]
568
- end
569
-
570
- it "extends procs" do
571
- @game.moves.respond_to?(:recent).should be_true
572
- @game.moves.recent.should == [@move_new]
573
- end
574
- end
575
-
576
- describe "list#get" do
577
- before do
578
- @game = Game.create
579
- @move = @game.moves.create
580
- end
581
-
582
- it "should not find items that don't exist" do
583
- @game.moves.get('does-not-exist').should be_nil
584
- end
585
-
586
- it "should find items that are in list" do
587
- @game.moves.get(@move.id).should == @move
588
- end
589
- end
590
-
591
- describe "list#get!" do
592
- before do
593
- @game = Game.create
594
- @move = @game.moves.create
595
- end
596
-
597
- it "should not find items that don't exist" do
598
- lambda {
599
- @game.moves.get!('does-not-exist')
600
- }.should raise_error(Toy::NotFound, 'Could not find document with id: "does-not-exist"')
601
- end
602
-
603
- it "should find items that are in list" do
604
- @game.moves.get!(@move.id).should == @move
605
- end
606
- end
607
- end