fake_dynamo 0.1.4 → 0.2.0
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.
- data/Gemfile +1 -1
- data/Guardfile +3 -0
- data/lib/fake_dynamo/api.yml +1 -1
- data/lib/fake_dynamo/api_2012-08-10.yml +1555 -0
- data/lib/fake_dynamo/db.rb +38 -5
- data/lib/fake_dynamo/item.rb +10 -0
- data/lib/fake_dynamo/key.rb +2 -10
- data/lib/fake_dynamo/key_schema.rb +27 -8
- data/lib/fake_dynamo/local_secondary_index.rb +27 -0
- data/lib/fake_dynamo/projection.rb +30 -0
- data/lib/fake_dynamo/table.rb +174 -76
- data/lib/fake_dynamo/validation.rb +66 -14
- data/lib/fake_dynamo/version.rb +1 -1
- data/lib/fake_dynamo.rb +2 -0
- data/spec/fake_dynamo/db_spec.rb +147 -53
- data/spec/fake_dynamo/server_spec.rb +5 -2
- data/spec/fake_dynamo/storage_spec.rb +3 -1
- data/spec/fake_dynamo/table_spec.rb +161 -39
- data/spec/fake_dynamo/validation_spec.rb +17 -18
- metadata +25 -28
- checksums.yaml +0 -7
@@ -6,9 +6,21 @@ module FakeDynamo
|
|
6
6
|
let(:data) do
|
7
7
|
{
|
8
8
|
"TableName" => "Table1",
|
9
|
+
"AttributeDefinitions" =>
|
10
|
+
[{"AttributeName" => "AttributeName1","AttributeType" => "S"},
|
11
|
+
{"AttributeName" => "AttributeName2","AttributeType" => "N"},
|
12
|
+
{"AttributeName" => "AttributeName3","AttributeType" => "N"}],
|
9
13
|
"KeySchema" =>
|
10
|
-
{"
|
11
|
-
|
14
|
+
[{"AttributeName" => "AttributeName1", "KeyType" => "HASH"},
|
15
|
+
{"AttributeName" => "AttributeName2", "KeyType" => "RANGE"}],
|
16
|
+
"LocalSecondaryIndexes" => [{
|
17
|
+
"IndexName" => "one",
|
18
|
+
"KeySchema" => [{"AttributeName" => "AttributeName1", "KeyType" => "HASH"},
|
19
|
+
{"AttributeName" => "AttributeName3", "KeyType" => "RANGE"}],
|
20
|
+
"Projection" => {
|
21
|
+
"ProjectionType" => "ALL"
|
22
|
+
}
|
23
|
+
}],
|
12
24
|
"ProvisionedThroughput" => {"ReadCapacityUnits" => 5,"WriteCapacityUnits" => 10}
|
13
25
|
}
|
14
26
|
end
|
@@ -21,18 +33,21 @@ module FakeDynamo
|
|
21
33
|
'AttributeName3' => { 'S' => "another" },
|
22
34
|
'binary' => { 'B' => Base64.encode64("binary") },
|
23
35
|
'binary_set' => { 'BS' => [Base64.encode64("binary")] }
|
24
|
-
}
|
36
|
+
},
|
37
|
+
'ReturnConsumedCapacity' => 'TOTAL'
|
38
|
+
}
|
25
39
|
end
|
26
40
|
|
27
41
|
let(:key) do
|
28
42
|
{'TableName' => 'Table1',
|
29
43
|
'Key' => {
|
30
|
-
'
|
31
|
-
'
|
32
|
-
}
|
44
|
+
'AttributeName1' => { 'S' => 'test' },
|
45
|
+
'AttributeName2' => { 'N' => '11' }
|
46
|
+
},
|
47
|
+
'ReturnConsumedCapacity' => 'TOTAL'}
|
33
48
|
end
|
34
49
|
|
35
|
-
let(:consumed_capacity) { { '
|
50
|
+
let(:consumed_capacity) { {'ConsumedCapacity' => { 'CapacityUnits' => 1, 'TableName' => 'Table1' }} }
|
36
51
|
|
37
52
|
subject { Table.new(data) }
|
38
53
|
|
@@ -102,8 +117,8 @@ module FakeDynamo
|
|
102
117
|
}})
|
103
118
|
response = subject.get_item({'TableName' => 'Table1',
|
104
119
|
'Key' => {
|
105
|
-
'
|
106
|
-
'
|
120
|
+
'AttributeName1' => { 'S' => 'test' },
|
121
|
+
'AttributeName2' => { 'N' => '3' }
|
107
122
|
}})
|
108
123
|
|
109
124
|
response['Item']['AttributeName3'].should eq('N' => '4.44444')
|
@@ -229,23 +244,24 @@ module FakeDynamo
|
|
229
244
|
it 'should return empty when the key is not found' do
|
230
245
|
response = subject.get_item({'TableName' => 'Table1',
|
231
246
|
'Key' => {
|
232
|
-
'
|
233
|
-
'
|
247
|
+
'AttributeName1' => { 'S' => 'xxx' },
|
248
|
+
'AttributeName2' => { 'N' => '11' }
|
234
249
|
}
|
235
250
|
})
|
236
|
-
response.should eq(
|
251
|
+
response.should eq({})
|
237
252
|
end
|
238
253
|
|
239
254
|
it 'should filter attributes' do
|
240
255
|
response = subject.get_item({'TableName' => 'Table1',
|
241
256
|
'Key' => {
|
242
|
-
'
|
243
|
-
'
|
257
|
+
'AttributeName1' => { 'S' => 'test' },
|
258
|
+
'AttributeName2' => { 'N' => '11' }
|
244
259
|
},
|
245
|
-
'AttributesToGet' => ['AttributeName3', 'xxx']
|
260
|
+
'AttributesToGet' => ['AttributeName3', 'xxx'],
|
261
|
+
'ReturnConsumedCapacity' => 'TOTAL'
|
246
262
|
})
|
247
|
-
response.should eq({ 'Item' => { 'AttributeName3' => { 'S' => 'another'}}
|
248
|
-
|
263
|
+
response.should eq({ 'Item' => { 'AttributeName3' => { 'S' => 'another'}}}
|
264
|
+
.merge(consumed_capacity))
|
249
265
|
end
|
250
266
|
end
|
251
267
|
|
@@ -316,7 +332,7 @@ module FakeDynamo
|
|
316
332
|
subject.get_item(key).should include('Item' => item['Item'])
|
317
333
|
|
318
334
|
expect do
|
319
|
-
key['Key']['
|
335
|
+
key['Key']['AttributeName1']['S'] = 'unknown'
|
320
336
|
put['AttributeUpdates'].merge!({ 'xx' => { 'Value' => { 'N' => 'one'}, 'Action' => 'ADD'}})
|
321
337
|
subject.update_item(key.merge(put))
|
322
338
|
end.to raise_error(ValidationException, /numeric/)
|
@@ -332,7 +348,7 @@ module FakeDynamo
|
|
332
348
|
end
|
333
349
|
|
334
350
|
it "should create new item if the key doesn't exist" do
|
335
|
-
key['Key']['
|
351
|
+
key['Key']['AttributeName1']['S'] = 'new'
|
336
352
|
subject.update_item(key.merge(put))
|
337
353
|
subject.get_item(key).should include( "Item"=>
|
338
354
|
{"AttributeName1"=>{"S"=>"new"},
|
@@ -341,7 +357,7 @@ module FakeDynamo
|
|
341
357
|
end
|
342
358
|
|
343
359
|
it "shouldn't create a new item if key doesn't exist and action is delete" do
|
344
|
-
key['Key']['
|
360
|
+
key['Key']['AttributeName1']['S'] = 'new'
|
345
361
|
subject.update_item(key.merge(delete))
|
346
362
|
subject.get_item(key).should eq(consumed_capacity)
|
347
363
|
end
|
@@ -384,12 +400,12 @@ module FakeDynamo
|
|
384
400
|
context '#query' do
|
385
401
|
subject do
|
386
402
|
t = Table.new(data)
|
387
|
-
t.put_item(item)
|
388
403
|
(1..3).each do |i|
|
389
404
|
(15.downto(1)).each do |j|
|
390
405
|
next if j.even?
|
391
406
|
item['Item']['AttributeName1']['S'] = "att#{i}"
|
392
407
|
item['Item']['AttributeName2']['N'] = j.to_s
|
408
|
+
item['Item']['AttributeName3'] = {'N' => j.to_s}
|
393
409
|
t.put_item(item)
|
394
410
|
end
|
395
411
|
end
|
@@ -400,23 +416,96 @@ module FakeDynamo
|
|
400
416
|
{
|
401
417
|
'TableName' => 'Table1',
|
402
418
|
'Limit' => 5,
|
403
|
-
'
|
404
|
-
|
405
|
-
|
406
|
-
|
419
|
+
'KeyConditions' => {
|
420
|
+
'AttributeName1' => {
|
421
|
+
'AttributeValueList' => [{'S' => 'att1'}],
|
422
|
+
'ComparisonOperator' => 'EQ'
|
423
|
+
},
|
424
|
+
'AttributeName2' => {
|
425
|
+
'AttributeValueList' => [{'N' => '1'}],
|
426
|
+
'ComparisonOperator' => 'GT'
|
427
|
+
}
|
428
|
+
},
|
429
|
+
'ScanIndexForward' => true
|
430
|
+
}
|
431
|
+
end
|
432
|
+
|
433
|
+
let(:index_query) do
|
434
|
+
{
|
435
|
+
'TableName' => 'Table1',
|
436
|
+
'Limit' => 5,
|
437
|
+
'IndexName' => 'one',
|
438
|
+
'KeyConditions' => {
|
439
|
+
'AttributeName1' => {
|
440
|
+
'AttributeValueList' => [{'S' => 'att1'}],
|
441
|
+
'ComparisonOperator' => 'EQ'
|
442
|
+
},
|
443
|
+
'AttributeName3' => {
|
444
|
+
'AttributeValueList' => [{'N' => '1'}],
|
445
|
+
'ComparisonOperator' => 'GT'
|
446
|
+
}
|
407
447
|
},
|
408
448
|
'ScanIndexForward' => true
|
409
449
|
}
|
410
450
|
end
|
411
451
|
|
452
|
+
context 'query projection' do
|
453
|
+
let(:query) do
|
454
|
+
{
|
455
|
+
'TableName' => 'Table1',
|
456
|
+
'Limit' => 5,
|
457
|
+
'Select' => 'ALL_PROJECTED_ATTRIBUTES',
|
458
|
+
'IndexName' => 'one',
|
459
|
+
'KeyConditions' => {
|
460
|
+
'AttributeName1' => {
|
461
|
+
'AttributeValueList' => [{'S' => 'test'}],
|
462
|
+
'ComparisonOperator' => 'EQ'
|
463
|
+
}
|
464
|
+
},
|
465
|
+
'ScanIndexForward' => true
|
466
|
+
}
|
467
|
+
end
|
468
|
+
|
469
|
+
let(:projection) { data['LocalSecondaryIndexes'][0]['Projection'] }
|
470
|
+
|
471
|
+
it 'should return all attributes' do
|
472
|
+
t = Table.new(data)
|
473
|
+
t.put_item(item)
|
474
|
+
response = t.query(query)
|
475
|
+
response['Items'].first.keys.size.should eq(5)
|
476
|
+
end
|
477
|
+
|
478
|
+
it 'should return return only the keys' do
|
479
|
+
projection['ProjectionType'] = 'KEYS_ONLY'
|
480
|
+
t = Table.new(data)
|
481
|
+
t.put_item(item)
|
482
|
+
response = t.query(query)
|
483
|
+
response['Items'].first.keys.size.should eq(3)
|
484
|
+
end
|
485
|
+
|
486
|
+
it 'should return return only the non key attributes' do
|
487
|
+
projection['ProjectionType'] = 'INCLUDE'
|
488
|
+
projection['NonKeyAttributes'] = ['binary_set']
|
489
|
+
t = Table.new(data)
|
490
|
+
t.put_item(item)
|
491
|
+
response = t.query(query)
|
492
|
+
response['Items'].first.keys.size.should eq(4)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
|
497
|
+
|
412
498
|
it 'should not allow count and attributes_to_get simutaneously' do
|
413
499
|
expect {
|
414
|
-
subject.query({'
|
500
|
+
subject.query({'Select' => 'COUNT', 'AttributesToGet' => ['xx']})
|
415
501
|
}.to raise_error(ValidationException, /count/i)
|
416
502
|
end
|
417
503
|
|
418
504
|
it 'should not allow to query on a table without rangekey' do
|
419
|
-
data['KeySchema'].
|
505
|
+
data['KeySchema'].delete_at(1)
|
506
|
+
data['AttributeDefinitions'].delete_at(1)
|
507
|
+
data['AttributeDefinitions'].delete_at(1)
|
508
|
+
data.delete('LocalSecondaryIndexes')
|
420
509
|
t = Table.new(data)
|
421
510
|
expect {
|
422
511
|
t.query(query)
|
@@ -434,13 +523,34 @@ module FakeDynamo
|
|
434
523
|
result['Count'].should eq(5)
|
435
524
|
end
|
436
525
|
|
526
|
+
it 'should fail if index name is missing' do
|
527
|
+
index_query.delete('IndexName')
|
528
|
+
expect { subject.query(index_query) }.to raise_error(ValidationException, /missed.*key/i)
|
529
|
+
end
|
530
|
+
|
531
|
+
it 'should fail if hash condition is missing' do
|
532
|
+
index_query['KeyConditions'].delete('AttributeName1')
|
533
|
+
expect { subject.query(index_query) }.to raise_error(ValidationException, /missed.*key.*schema/i)
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'should fail if hash condition is not EQ' do
|
537
|
+
index_query['KeyConditions']['AttributeName1']['ComparisonOperator'] = 'GT'
|
538
|
+
expect { subject.query(index_query) }.to raise_error(ValidationException, /condition not supported/i)
|
539
|
+
end
|
540
|
+
|
541
|
+
it 'should handle index query' do
|
542
|
+
result = subject.query(index_query)
|
543
|
+
result['Count'].should eq(5)
|
544
|
+
end
|
545
|
+
|
546
|
+
|
437
547
|
it 'should handle scanindexforward' do
|
438
548
|
result = subject.query(query)
|
439
549
|
result['Items'].first['AttributeName2'].should eq({'N' => '3'})
|
440
550
|
result = subject.query(query.merge({'ScanIndexForward' => false}))
|
441
551
|
result['Items'].first['AttributeName2'].should eq({'N' => '15'})
|
442
552
|
|
443
|
-
query['ExclusiveStartKey'] = { '
|
553
|
+
query['ExclusiveStartKey'] = { 'AttributeName1' => { 'S' => 'att1' }, 'AttributeName2' => { "N" => '7' }}
|
444
554
|
result = subject.query(query)
|
445
555
|
result['Items'][0]['AttributeName1'].should eq({'S' => 'att1'})
|
446
556
|
result['Items'][0]['AttributeName2'].should eq({'N' => '9'})
|
@@ -449,7 +559,7 @@ module FakeDynamo
|
|
449
559
|
result['Items'][0]['AttributeName1'].should eq({'S' => 'att1'})
|
450
560
|
result['Items'][0]['AttributeName2'].should eq({'N' => '5'})
|
451
561
|
|
452
|
-
query['ExclusiveStartKey'] = { '
|
562
|
+
query['ExclusiveStartKey'] = { 'AttributeName1' => { 'S' => 'att1' }, 'AttributeName2' => { "N" => '8' }}
|
453
563
|
result = subject.query(query)
|
454
564
|
result['Items'][0]['AttributeName1'].should eq({'S' => 'att1'})
|
455
565
|
result['Items'][0]['AttributeName2'].should eq({'N' => '9'})
|
@@ -461,7 +571,7 @@ module FakeDynamo
|
|
461
571
|
|
462
572
|
it 'should return lastevaluated key' do
|
463
573
|
result = subject.query(query)
|
464
|
-
result['LastEvaluatedKey'].should == {"
|
574
|
+
result['LastEvaluatedKey'].should == {"AttributeName1"=>{"S"=>"att1"}, "AttributeName2"=>{"N"=>"11"}}
|
465
575
|
result = subject.query(query.merge('Limit' => 100))
|
466
576
|
result['LastEvaluatedKey'].should be_nil
|
467
577
|
|
@@ -471,26 +581,26 @@ module FakeDynamo
|
|
471
581
|
end
|
472
582
|
|
473
583
|
it 'should handle exclusive start key' do
|
474
|
-
result = subject.query(query.merge({'ExclusiveStartKey' => {"
|
584
|
+
result = subject.query(query.merge({'ExclusiveStartKey' => {"AttributeName1"=>{"S"=>"att1"}, "AttributeName2"=>{"N"=>"7"}}}))
|
475
585
|
result['Count'].should eq(4)
|
476
586
|
result['Items'].first['AttributeName2'].should eq({'N' => '9'})
|
477
|
-
result = subject.query(query.merge({'ExclusiveStartKey' => {"
|
587
|
+
result = subject.query(query.merge({'ExclusiveStartKey' => {"AttributeName1"=>{"S"=>"att1"}, "AttributeName2"=>{"N"=>"8"}}}))
|
478
588
|
result['Count'].should eq(4)
|
479
589
|
result['Items'].first['AttributeName2'].should eq({'N' => '9'})
|
480
|
-
result = subject.query(query.merge({'ExclusiveStartKey' => {"
|
590
|
+
result = subject.query(query.merge({'ExclusiveStartKey' => {"AttributeName1"=>{"S"=>"att1"}, "AttributeName2"=>{"N"=>"88"}}}))
|
481
591
|
result['Count'].should eq(0)
|
482
592
|
result['Items'].should be_empty
|
483
593
|
end
|
484
594
|
|
485
595
|
|
486
596
|
it 'should return all elements if not rangekeycondition is given' do
|
487
|
-
query.delete('
|
597
|
+
query['KeyConditions'].delete('AttributeName2')
|
488
598
|
result = subject.query(query)
|
489
599
|
result['Count'].should eq(5)
|
490
600
|
end
|
491
601
|
|
492
602
|
it 'should handle between operator' do
|
493
|
-
query['
|
603
|
+
query['KeyConditions']['AttributeName2'] = {
|
494
604
|
'AttributeValueList' => [{'N' => '1'}, {'N' => '7'}],
|
495
605
|
'ComparisonOperator' => 'BETWEEN'
|
496
606
|
}
|
@@ -534,10 +644,22 @@ module FakeDynamo
|
|
534
644
|
|
535
645
|
it 'should not allow count and attributes_to_get simutaneously' do
|
536
646
|
expect {
|
537
|
-
subject.scan({'
|
647
|
+
subject.scan({'Select' => 'COUNT', 'AttributesToGet' => ['xx']})
|
538
648
|
}.to raise_error(ValidationException, /count/i)
|
539
649
|
end
|
540
650
|
|
651
|
+
it 'should only return count' do
|
652
|
+
scan['Select'] = 'COUNT'
|
653
|
+
response = subject.scan(scan)
|
654
|
+
response['Count'].should eq(24)
|
655
|
+
response['Items'].should be_nil
|
656
|
+
end
|
657
|
+
|
658
|
+
it 'should not allow ALL_PROJECTED_ATTRIBUTES' do
|
659
|
+
scan['Select'] = 'ALL_PROJECTED_ATTRIBUTES'
|
660
|
+
expect { subject.scan(scan) }.to raise_error(ValidationException, /querying.*indexname/i)
|
661
|
+
end
|
662
|
+
|
541
663
|
it 'should only allow limit greater than zero' do
|
542
664
|
expect {
|
543
665
|
subject.scan(scan.merge('Limit' => 0))
|
@@ -555,7 +677,7 @@ module FakeDynamo
|
|
555
677
|
it 'should return lastevaluated key' do
|
556
678
|
scan['Limit'] = 5
|
557
679
|
result = subject.scan(scan)
|
558
|
-
result['LastEvaluatedKey'].should == {"
|
680
|
+
result['LastEvaluatedKey'].should == {"AttributeName1"=>{"S"=>"att1"}, "AttributeName2"=>{"N"=>"9"}}
|
559
681
|
result = subject.scan(scan.merge('Limit' => 100))
|
560
682
|
result['LastEvaluatedKey'].should be_nil
|
561
683
|
|
@@ -565,12 +687,12 @@ module FakeDynamo
|
|
565
687
|
end
|
566
688
|
|
567
689
|
it 'should handle ordering' do
|
568
|
-
scan['ExclusiveStartKey'] = { '
|
690
|
+
scan['ExclusiveStartKey'] = { 'AttributeName1' => { 'S' => 'att2' }, 'AttributeName2' => { "N" => '7' }}
|
569
691
|
result = subject.scan(scan)
|
570
692
|
result['Items'][0]['AttributeName1'].should eq({'S' => 'att2'})
|
571
693
|
result['Items'][0]['AttributeName2'].should eq({'N' => '9'})
|
572
694
|
|
573
|
-
scan['ExclusiveStartKey'] = { '
|
695
|
+
scan['ExclusiveStartKey'] = { 'AttributeName1' => { 'S' => 'att2' }, 'AttributeName2' => { "N" => '8' }}
|
574
696
|
result['Items'][0]['AttributeName1'].should eq({'S' => 'att2'})
|
575
697
|
result['Items'][0]['AttributeName2'].should eq({'N' => '9'})
|
576
698
|
end
|
@@ -9,9 +9,12 @@ module FakeDynamo
|
|
9
9
|
let(:data) do
|
10
10
|
{
|
11
11
|
"TableName" => "Table1",
|
12
|
+
"AttributeDefinitions" =>
|
13
|
+
[{"AttributeName" => "AttributeName1","AttributeType" => "S"},
|
14
|
+
{"AttributeName" => "AttributeName2","AttributeType" => "N"}],
|
12
15
|
"KeySchema" =>
|
13
|
-
{"
|
14
|
-
|
16
|
+
[{"AttributeName" => "AttributeName1","KeyType" => "HASH"},
|
17
|
+
{"AttributeName" => "AttributeName2","KeyType" => "RANGE"}],
|
15
18
|
"ProvisionedThroughput" => {"ReadCapacityUnits" => 5,"WriteCapacityUnits" => 10}
|
16
19
|
}
|
17
20
|
end
|
@@ -38,34 +41,30 @@ module FakeDynamo
|
|
38
41
|
|
39
42
|
context '#validate_key_data' do
|
40
43
|
let(:schema) do
|
41
|
-
KeySchema.new(
|
44
|
+
KeySchema.new(
|
45
|
+
[{ 'AttributeName' => 'id', 'KeyType' => 'HASH'}],
|
46
|
+
[{"AttributeName" => "id","AttributeType" => "S"}])
|
42
47
|
end
|
43
48
|
|
44
49
|
let(:schema_with_range) do
|
45
|
-
KeySchema.new(
|
46
|
-
|
50
|
+
KeySchema.new(
|
51
|
+
[{ 'AttributeName' => 'id', 'KeyType' => 'HASH'},
|
52
|
+
{ 'AttributeName' => 'time', 'KeyType' => 'RANGE'}],
|
53
|
+
[{ 'AttributeName' => 'id', 'AttributeType' => 'S'},
|
54
|
+
{ 'AttributeName' => 'time', 'AttributeType' => 'N'}])
|
47
55
|
end
|
48
56
|
|
49
57
|
it 'should validate the schema' do
|
50
|
-
[[{'
|
51
|
-
[{'
|
52
|
-
[{'
|
53
|
-
[{'
|
58
|
+
[[{'id' => { 'N' => '1234' }}, schema, /type mismatch/i],
|
59
|
+
[{'id' => { 'S' => '1234' }}, schema_with_range, /not match/i],
|
60
|
+
[{'id' => { 'S' => '1234' }, 'time' => { 'N' => '1234'}}, schema, /not match/i],
|
61
|
+
[{'id' => { 'S' => '1234' }, 'time' => { 'S' => '1234'}}, schema_with_range, /type mismatch/i]
|
54
62
|
].each do |data, schema, message|
|
55
63
|
expect do
|
56
64
|
subject.validate_key_data(data, schema)
|
57
65
|
end.to raise_error(ValidationException, message)
|
58
66
|
end
|
59
67
|
end
|
60
|
-
|
61
|
-
it 'should allow null comparison operator' do
|
62
|
-
subject.validate_payload('Scan', {
|
63
|
-
'TableName' => 'Table1',
|
64
|
-
'ScanFilter' => {
|
65
|
-
'age' => { 'ComparisonOperator' => 'NULL' }
|
66
|
-
}
|
67
|
-
})
|
68
|
-
end
|
69
68
|
end
|
70
69
|
|
71
70
|
end
|
metadata
CHANGED
@@ -1,57 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fake_dynamo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Anantha Kumaran
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2013-04-22 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: sinatra
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70301515417000 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '0'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
|
-
version_requirements:
|
23
|
-
requirements:
|
24
|
-
- - '>='
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
24
|
+
version_requirements: *70301515417000
|
27
25
|
- !ruby/object:Gem::Dependency
|
28
26
|
name: activesupport
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
27
|
+
requirement: &70301515416500 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
30
29
|
requirements:
|
31
|
-
- - '>='
|
30
|
+
- - ! '>='
|
32
31
|
- !ruby/object:Gem::Version
|
33
32
|
version: '0'
|
34
33
|
type: :runtime
|
35
34
|
prerelease: false
|
36
|
-
version_requirements:
|
37
|
-
requirements:
|
38
|
-
- - '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
35
|
+
version_requirements: *70301515416500
|
41
36
|
- !ruby/object:Gem::Dependency
|
42
37
|
name: json
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirement: &70301515416080 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
44
40
|
requirements:
|
45
|
-
- - '>='
|
41
|
+
- - ! '>='
|
46
42
|
- !ruby/object:Gem::Version
|
47
43
|
version: '0'
|
48
44
|
type: :runtime
|
49
45
|
prerelease: false
|
50
|
-
version_requirements:
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
46
|
+
version_requirements: *70301515416080
|
55
47
|
description:
|
56
48
|
email:
|
57
49
|
- ananthakumaran@gmail.com
|
@@ -72,6 +64,7 @@ files:
|
|
72
64
|
- fake_dynamo.gemspec
|
73
65
|
- lib/fake_dynamo.rb
|
74
66
|
- lib/fake_dynamo/api.yml
|
67
|
+
- lib/fake_dynamo/api_2012-08-10.yml
|
75
68
|
- lib/fake_dynamo/attribute.rb
|
76
69
|
- lib/fake_dynamo/db.rb
|
77
70
|
- lib/fake_dynamo/exceptions.rb
|
@@ -79,6 +72,8 @@ files:
|
|
79
72
|
- lib/fake_dynamo/item.rb
|
80
73
|
- lib/fake_dynamo/key.rb
|
81
74
|
- lib/fake_dynamo/key_schema.rb
|
75
|
+
- lib/fake_dynamo/local_secondary_index.rb
|
76
|
+
- lib/fake_dynamo/projection.rb
|
82
77
|
- lib/fake_dynamo/server.rb
|
83
78
|
- lib/fake_dynamo/storage.rb
|
84
79
|
- lib/fake_dynamo/table.rb
|
@@ -94,26 +89,27 @@ files:
|
|
94
89
|
- spec/spec_helper.rb
|
95
90
|
homepage:
|
96
91
|
licenses: []
|
97
|
-
metadata: {}
|
98
92
|
post_install_message:
|
99
93
|
rdoc_options: []
|
100
94
|
require_paths:
|
101
95
|
- lib
|
102
96
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
103
98
|
requirements:
|
104
|
-
- - '>='
|
99
|
+
- - ! '>='
|
105
100
|
- !ruby/object:Gem::Version
|
106
101
|
version: 1.9.0
|
107
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
108
104
|
requirements:
|
109
|
-
- - '>='
|
105
|
+
- - ! '>='
|
110
106
|
- !ruby/object:Gem::Version
|
111
107
|
version: '0'
|
112
108
|
requirements: []
|
113
109
|
rubyforge_project:
|
114
|
-
rubygems_version:
|
110
|
+
rubygems_version: 1.8.15
|
115
111
|
signing_key:
|
116
|
-
specification_version:
|
112
|
+
specification_version: 3
|
117
113
|
summary: local hosted, inmemory fake dynamodb
|
118
114
|
test_files:
|
119
115
|
- spec/fake_dynamo/db_spec.rb
|
@@ -124,3 +120,4 @@ test_files:
|
|
124
120
|
- spec/fake_dynamo/table_spec.rb
|
125
121
|
- spec/fake_dynamo/validation_spec.rb
|
126
122
|
- spec/spec_helper.rb
|
123
|
+
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 0f4631cc05b44fc6f658eb3a18c89ba2d4f3599b
|
4
|
-
data.tar.gz: 67d433993da543cb68b6eed85ffae822f981a085
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 9b52c4ef7c46f44efe512dfb8a7ce6ebf9f2cce713d1406d1a603226a298cb2c097b76ea0fe3993815c27f24fc5c39e99d4b84538dc14db7ca69bed8b49588a8
|
7
|
-
data.tar.gz: ee52a997e6aeccc0424313925fcf4d5524cb8d823495289de6670677e1f3046299746711455c1a00a9239e0bc83ab2987b214decf5412f4bb12d2f7b925bd03e
|