strokedb 0.0.2.1 → 0.0.2.2
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/README +18 -20
- data/bench.html +4001 -0
- data/bin/strokedb +14 -0
- data/examples/movies.rb +105 -0
- data/examples/movies2.rb +97 -0
- data/examples/strokewiki/README +28 -0
- data/examples/strokewiki/view/edit.xhtml +27 -0
- data/examples/strokewiki/view/new.xhtml +26 -0
- data/examples/strokewiki/view/pages.xhtml +27 -0
- data/examples/strokewiki/view/show.xhtml +40 -0
- data/examples/strokewiki/view/versions.xhtml +25 -0
- data/examples/strokewiki/wiki.rb +106 -0
- data/examples/todo.rb +92 -0
- data/lib/strokedb.rb +85 -0
- data/lib/{config → strokedb}/config.rb +14 -9
- data/lib/strokedb/console.rb +87 -0
- data/lib/strokedb/core_ext.rb +10 -0
- data/lib/{util/ext → strokedb/core_ext}/blank.rb +1 -1
- data/lib/{util/ext → strokedb/core_ext}/enumerable.rb +0 -0
- data/lib/{util/ext → strokedb/core_ext}/fixnum.rb +0 -0
- data/lib/strokedb/core_ext/float.rb +4 -0
- data/lib/{util/ext → strokedb/core_ext}/hash.rb +0 -0
- data/lib/strokedb/core_ext/infinity.rb +33 -0
- data/lib/strokedb/core_ext/kernel.rb +41 -0
- data/lib/strokedb/core_ext/object.rb +16 -0
- data/lib/{util/ext → strokedb/core_ext}/string.rb +28 -1
- data/lib/strokedb/core_ext/symbol.rb +13 -0
- data/lib/strokedb/data_structures.rb +5 -0
- data/lib/strokedb/data_structures/chunked_skiplist.rb +123 -0
- data/lib/{data_structures → strokedb/data_structures}/inverted_list.rb +0 -0
- data/lib/{data_structures → strokedb/data_structures}/point_query.rb +0 -0
- data/lib/strokedb/data_structures/simple_skiplist.rb +350 -0
- data/lib/{data_structures → strokedb/data_structures}/skiplist.rb +1 -1
- data/lib/{document → strokedb}/document.rb +180 -71
- data/lib/{document → strokedb/document}/callback.rb +0 -0
- data/lib/{document → strokedb/document}/delete.rb +2 -2
- data/lib/strokedb/document/dsl.rb +4 -0
- data/lib/{document → strokedb/document/dsl}/associations.rb +0 -0
- data/lib/{document → strokedb/document/dsl}/coercions.rb +0 -0
- data/lib/strokedb/document/dsl/meta_dsl.rb +7 -0
- data/lib/{document → strokedb/document/dsl}/validations.rb +26 -21
- data/lib/{document → strokedb/document/dsl}/virtualize.rb +0 -0
- data/lib/{document → strokedb/document}/meta.rb +92 -29
- data/lib/{document → strokedb/document}/slot.rb +17 -5
- data/lib/{document → strokedb/document}/util.rb +0 -0
- data/lib/{document → strokedb/document}/versions.rb +2 -2
- data/lib/strokedb/index.rb +2 -0
- data/lib/strokedb/nsurl.rb +24 -0
- data/lib/strokedb/store.rb +149 -0
- data/lib/strokedb/stores.rb +6 -0
- data/lib/{stores → strokedb/stores}/chainable_storage.rb +20 -14
- data/lib/strokedb/stores/file_storage.rb +118 -0
- data/lib/{stores/inverted_list_index → strokedb/stores}/inverted_list_file_storage.rb +50 -0
- data/lib/strokedb/stores/memory_storage.rb +80 -0
- data/lib/{stores → strokedb/stores}/remote_store.rb +10 -4
- data/lib/strokedb/sync.rb +4 -0
- data/lib/{sync → strokedb/sync}/chain_sync.rb +0 -0
- data/lib/{sync → strokedb/sync}/diff.rb +12 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/array.rb +1 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/default.rb +0 -0
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/hash.rb +1 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/string.rb +1 -1
- data/lib/{sync → strokedb/sync}/lamport_timestamp.rb +0 -0
- data/lib/{sync → strokedb/sync}/store_sync.rb +15 -7
- data/lib/strokedb/transaction.rb +78 -0
- data/lib/{util → strokedb}/util.rb +14 -7
- data/lib/strokedb/util/attach_dsl.rb +29 -0
- data/lib/{util → strokedb/util}/blankslate.rb +0 -0
- data/lib/strokedb/util/class_optimization.rb +93 -0
- data/lib/{util → strokedb/util}/inflect.rb +0 -0
- data/lib/strokedb/util/java_util.rb +13 -0
- data/lib/{util → strokedb/util}/lazy_array.rb +0 -0
- data/lib/{util → strokedb/util}/lazy_mapping_array.rb +4 -0
- data/lib/{util → strokedb/util}/lazy_mapping_hash.rb +0 -0
- data/lib/{util → strokedb/util}/serialization.rb +21 -0
- data/lib/strokedb/util/uuid.rb +159 -0
- data/lib/{util → strokedb/util}/xml.rb +0 -0
- data/lib/{view → strokedb}/view.rb +2 -2
- data/lib/strokedb/volumes.rb +5 -0
- data/lib/strokedb/volumes/archive_volume.rb +165 -0
- data/lib/strokedb/volumes/block_volume.rb +169 -0
- data/lib/strokedb/volumes/distributed_pointer.rb +43 -0
- data/lib/strokedb/volumes/fixed_length_skiplist_volume.rb +109 -0
- data/lib/strokedb/volumes/map_volume.rb +268 -0
- data/meta/MANIFEST +175 -0
- data/script/console +2 -70
- data/spec/integration/remote_store_spec.rb +70 -0
- data/spec/integration/search_spec.rb +76 -0
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/lib/spec_helper.rb +1 -0
- data/spec/lib/strokedb/config_spec.rb +250 -0
- data/spec/lib/strokedb/core_ext/blank_spec.rb +20 -0
- data/spec/lib/strokedb/core_ext/extract_spec.rb +42 -0
- data/spec/lib/strokedb/core_ext/float_spec.rb +62 -0
- data/spec/lib/strokedb/core_ext/infinity_spec.rb +40 -0
- data/spec/lib/strokedb/core_ext/spec_helper.rb +1 -0
- data/spec/lib/strokedb/core_ext/string_spec.rb +25 -0
- data/spec/lib/strokedb/core_ext/symbol_spec.rb +8 -0
- data/spec/lib/strokedb/data_structures/chunked_skiplist_spec.rb +144 -0
- data/spec/lib/strokedb/data_structures/inverted_list_spec.rb +172 -0
- data/spec/lib/strokedb/data_structures/simple_skiplist_spec.rb +200 -0
- data/spec/lib/strokedb/data_structures/skiplist_spec.rb +253 -0
- data/spec/lib/strokedb/data_structures/spec_helper.rb +1 -0
- data/spec/lib/strokedb/document/associations_spec.rb +319 -0
- data/spec/lib/strokedb/document/callbacks_spec.rb +134 -0
- data/spec/lib/strokedb/document/coercions_spec.rb +110 -0
- data/spec/lib/strokedb/document/document_spec.rb +1063 -0
- data/spec/lib/strokedb/document/meta_meta_spec.rb +30 -0
- data/spec/lib/strokedb/document/meta_spec.rb +435 -0
- data/spec/lib/strokedb/document/metaslot_spec.rb +43 -0
- data/spec/lib/strokedb/document/slot_spec.rb +130 -0
- data/spec/lib/strokedb/document/spec_helper.rb +1 -0
- data/spec/lib/strokedb/document/validations_spec.rb +1081 -0
- data/spec/lib/strokedb/document/virtualize_spec.rb +80 -0
- data/spec/lib/strokedb/nsurl_spec.rb +73 -0
- data/spec/lib/strokedb/spec_helper.rb +1 -0
- data/spec/lib/strokedb/stores/chained_storages_spec.rb +116 -0
- data/spec/lib/strokedb/stores/spec_helper.rb +1 -0
- data/spec/lib/strokedb/stores/store_spec.rb +201 -0
- data/spec/lib/strokedb/stores/transaction_spec.rb +107 -0
- data/spec/lib/strokedb/sync/chain_sync_spec.rb +43 -0
- data/spec/lib/strokedb/sync/diff_spec.rb +111 -0
- data/spec/lib/strokedb/sync/lamport_timestamp_spec.rb +174 -0
- data/spec/lib/strokedb/sync/slot_diff_spec.rb +164 -0
- data/spec/lib/strokedb/sync/spec_helper.rb +1 -0
- data/spec/lib/strokedb/sync/store_sync_spec.rb +181 -0
- data/spec/lib/strokedb/sync/stroke_diff/array_spec.rb +97 -0
- data/spec/lib/strokedb/sync/stroke_diff/complex_spec.rb +58 -0
- data/spec/lib/strokedb/sync/stroke_diff/hash_spec.rb +144 -0
- data/spec/lib/strokedb/sync/stroke_diff/scalar_spec.rb +23 -0
- data/spec/lib/strokedb/sync/stroke_diff/spec_helper.rb +25 -0
- data/spec/lib/strokedb/sync/stroke_diff/string_spec.rb +61 -0
- data/spec/lib/strokedb/util/attach_dsl_spec.rb +45 -0
- data/spec/lib/strokedb/util/inflect_spec.rb +14 -0
- data/spec/lib/strokedb/util/lazy_array_spec.rb +157 -0
- data/spec/lib/strokedb/util/lazy_mapping_array_spec.rb +174 -0
- data/spec/lib/strokedb/util/lazy_mapping_hash_spec.rb +92 -0
- data/spec/lib/strokedb/util/spec_helper.rb +1 -0
- data/spec/lib/strokedb/util/uuid_spec.rb +46 -0
- data/spec/lib/strokedb/view_spec.rb +228 -0
- data/spec/lib/strokedb/volumes/archive_volume_spec.rb +105 -0
- data/spec/lib/strokedb/volumes/block_volume_spec.rb +100 -0
- data/spec/lib/strokedb/volumes/distributed_pointer_spec.rb +14 -0
- data/spec/lib/strokedb/volumes/fixed_length_skiplist_volume_spec.rb +177 -0
- data/spec/lib/strokedb/volumes/map_volume_spec.rb +172 -0
- data/spec/lib/strokedb/volumes/spec_helper.rb +1 -0
- data/spec/regression/docref_spec.rb +94 -0
- data/spec/regression/meta_spec.rb +23 -0
- data/spec/regression/spec_helper.rb +1 -0
- data/spec/regression/sync_spec.rb +36 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/temp/storages/TIMESTAMP +1 -0
- data/spec/temp/storages/UUID +1 -0
- data/spec/temp/storages/database-sync/TIMESTAMP +1 -0
- data/spec/temp/storages/database-sync/UUID +1 -0
- data/spec/temp/storages/database-sync/config +1 -0
- data/spec/temp/storages/database-sync/file/LAST +1 -0
- data/spec/temp/storages/database-sync/file/bd/f6/bdf675e5-8a7b-494e-97f2-f74a14ccd95d.av +0 -0
- data/spec/temp/storages/database-sync/file/uindex.wal +0 -0
- data/spec/temp/storages/database-sync/inverted_list_file/INVERTED_INDEX +1 -0
- data/spec/temp/storages/inverted_list_storage/INVERTED_INDEX +0 -0
- data/strokedb.gemspec +120 -0
- data/task/benchmark.task +9 -0
- data/task/ditz.task +30 -0
- data/task/echoe.rb +17 -0
- data/task/rcov.task +50 -0
- data/task/rdoc.task +10 -0
- data/task/rspec.task +0 -0
- data/vendor/java_inline.rb +106 -0
- data/vendor/rbmodexcl/mrimodexcl.rb +82 -0
- data/vendor/rbmodexcl/rbmodexcl.rb +5 -0
- data/vendor/rbmodexcl/rbxmodexcl.rb +48 -0
- data/vendor/rbmodexcl/spec/unextend_spec.rb +50 -0
- data/vendor/rbmodexcl/spec/uninclude_spec.rb +26 -0
- metadata +271 -79
- data/CONTRIBUTORS +0 -7
- data/CREDITS +0 -13
- data/bin/sdbc +0 -2
- data/lib/init.rb +0 -57
- data/lib/stores/inverted_list_index/inverted_list_index.rb +0 -49
- data/lib/stores/skiplist_store/chunk.rb +0 -119
- data/lib/stores/skiplist_store/chunk_storage.rb +0 -21
- data/lib/stores/skiplist_store/file_chunk_storage.rb +0 -44
- data/lib/stores/skiplist_store/memory_chunk_storage.rb +0 -37
- data/lib/stores/skiplist_store/skiplist_store.rb +0 -217
- data/lib/stores/store.rb +0 -5
- data/lib/sync/stroke_diff/stroke_diff.rb +0 -9
- data/lib/util/ext/object.rb +0 -8
- data/lib/util/java_util.rb +0 -9
- data/lib/util/trigger_partition.rb +0 -136
- data/strokedb.rb +0 -75
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Transaction', :shared => true do
|
|
4
|
+
|
|
5
|
+
it "should have UUID" do
|
|
6
|
+
@txn.uuid.should match(/#{UUID_RE}/)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should act as a store for documents initialized within transaction scope" do
|
|
10
|
+
@txn.execute do
|
|
11
|
+
@doc = Document.new
|
|
12
|
+
@doc.store.should == @txn
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should revert newly instantiated documents' store to main one outside of transaction scope" do
|
|
17
|
+
@txn.execute do
|
|
18
|
+
@doc = Document.new
|
|
19
|
+
end
|
|
20
|
+
@doc.store.should == @txn.store
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should acts as a store for already initialized documents" do
|
|
24
|
+
@doc = Document.new
|
|
25
|
+
@txn.execute do
|
|
26
|
+
@doc.store.should == @txn
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should return block result on block execution" do
|
|
31
|
+
@txn.execute do
|
|
32
|
+
:some_result
|
|
33
|
+
end.should == :some_result
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should be able to find already existing document within transaction scope" do
|
|
37
|
+
@doc = Document.create!
|
|
38
|
+
@txn.execute do
|
|
39
|
+
Document.find(@doc.uuid).should == @doc
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should be able to save new documents within block execution without exposing them to original storage" do
|
|
44
|
+
@txn.execute do
|
|
45
|
+
@doc = Document.create!
|
|
46
|
+
Document.find(@doc.uuid).should == @doc
|
|
47
|
+
end
|
|
48
|
+
Document.find(@doc.uuid).should be_nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should see its own head version of the document" do
|
|
52
|
+
@doc = Document.create!
|
|
53
|
+
@txn.execute do |txn|
|
|
54
|
+
@doc.update_slots! :new_version => 'yes'
|
|
55
|
+
@doc.store.head_version(@doc.uuid).should == @doc.version
|
|
56
|
+
end
|
|
57
|
+
@doc.store.head_version(@doc.uuid).should == @doc.versions.previous.version
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should be able to commit transaction" do
|
|
61
|
+
@txn.execute do |txn|
|
|
62
|
+
@doc = Document.create!
|
|
63
|
+
txn.commit!
|
|
64
|
+
end
|
|
65
|
+
Document.find(@doc.uuid).should == @doc
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should be able to rollback transaction" do
|
|
69
|
+
@txn.execute do |txn|
|
|
70
|
+
@doc = Document.create!
|
|
71
|
+
txn.rollback!
|
|
72
|
+
Document.find(@doc.uuid).should be_nil
|
|
73
|
+
end
|
|
74
|
+
Document.find(@doc.uuid).should be_nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should pop transaction on code that raises some exception" do
|
|
78
|
+
lambda do
|
|
79
|
+
@txn.execute do |txn|
|
|
80
|
+
raise Exception
|
|
81
|
+
end
|
|
82
|
+
end.should raise_error(Exception)
|
|
83
|
+
Thread.current[:strokedb_transactions].should be_empty
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should pop transaction on code that raises no exception" do
|
|
87
|
+
lambda do
|
|
88
|
+
@txn.execute do |txn|
|
|
89
|
+
end
|
|
90
|
+
end.should_not raise_error(Exception)
|
|
91
|
+
Thread.current[:strokedb_transactions].should be_empty
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe "New", Transaction do
|
|
98
|
+
|
|
99
|
+
before(:each) do
|
|
100
|
+
StrokeDB::Config.build :default => true, :storages => [:memory], :base_path => TEMP_STORAGES + '/txn'
|
|
101
|
+
@txn = Transaction.new(:store => StrokeDB.default_store)
|
|
102
|
+
Thread.current[:strokedb_transactions] = nil
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it_should_behave_like 'Transaction'
|
|
106
|
+
|
|
107
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Chain sync" do
|
|
4
|
+
include ChainSync
|
|
5
|
+
before(:each) do
|
|
6
|
+
@chain1 = %w[ a b c ]
|
|
7
|
+
@chain2 = %w[ a b c d e ]
|
|
8
|
+
@chain3 = %w[ a b q w r ]
|
|
9
|
+
@chain4 = %w[ t y u i o ]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should raise NonMatchingChains for non-matching chains" do
|
|
13
|
+
lambda{ sync_chains(@chain1, @chain4) }.should raise_error(ChainSync::NonMatchingChains)
|
|
14
|
+
lambda{ sync_chains(@chain4, @chain1) }.should raise_error(ChainSync::NonMatchingChains)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should not raise NonMatchingChains for matching chains" do
|
|
18
|
+
lambda{ sync_chains(@chain1, @chain2) }.should_not raise_error
|
|
19
|
+
lambda{ sync_chains(@chain1, @chain3) }.should_not raise_error
|
|
20
|
+
lambda{ sync_chains(@chain2, @chain3) }.should_not raise_error
|
|
21
|
+
lambda{ sync_chains(@chain2, @chain1) }.should_not raise_error
|
|
22
|
+
lambda{ sync_chains(@chain3, @chain1) }.should_not raise_error
|
|
23
|
+
lambda{ sync_chains(@chain3, @chain2) }.should_not raise_error
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should resolve up-to-date situation" do
|
|
27
|
+
sync_chains(@chain1, @chain2).should == :up_to_date
|
|
28
|
+
sync_chains(@chain2, @chain1).should_not == :up_to_date
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should resolve fast-forward situation" do
|
|
32
|
+
status, subchain = sync_chains(@chain2, @chain1)
|
|
33
|
+
status.should == :fast_forward
|
|
34
|
+
subchain.should == %w[ c d e ]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should resolve merge situation" do
|
|
38
|
+
status, subchain_from, subchain_to = sync_chains(@chain2, @chain3)
|
|
39
|
+
status.should == :merge
|
|
40
|
+
subchain_from.should == %w[ b c d e ]
|
|
41
|
+
subchain_to.should == %w[ b q w r ]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Diffing documents", :shared => true do
|
|
4
|
+
it "should have from and to specified" do
|
|
5
|
+
[:from,:to].each do |slotname|
|
|
6
|
+
@diff[slotname].should be_a_kind_of(Document)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should be appliable as patch" do
|
|
11
|
+
from = @from.dup
|
|
12
|
+
@diff.patch!(from)
|
|
13
|
+
(from.slotnames - ['version','previous_version']).should == (@to.slotnames-['version','previous_version'])
|
|
14
|
+
(from.slotnames - ['version','previous_version']).each do |slotname|
|
|
15
|
+
from[slotname].should == @to[slotname]
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "Diffing documents with slot added" do
|
|
21
|
+
before(:each) do
|
|
22
|
+
@store = setup_default_store
|
|
23
|
+
@from = Document.create! :slot1 => 1
|
|
24
|
+
@to = Document.create! :slot1 => 1, :slot2 => 2
|
|
25
|
+
@diff = @to.diff(@from)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should list added slot" do
|
|
29
|
+
@diff.added_slots.keys.to_set.should == ['slot2'].to_set
|
|
30
|
+
@diff.added_slots['slot2'].should == 2
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
it "should report as modified" do
|
|
35
|
+
@diff.should be_different
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it_should_behave_like "Diffing documents"
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "Diffing documents with slot removed" do
|
|
43
|
+
before(:each) do
|
|
44
|
+
@store = setup_default_store
|
|
45
|
+
@from = Document.create! :slot1 => 1, :slot2 => 2
|
|
46
|
+
@to = Document.create! :slot1 => 1
|
|
47
|
+
@diff = @to.diff(@from)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should list removed slot" do
|
|
51
|
+
@diff.removed_slots.keys.to_set.should == ['slot2'].to_set
|
|
52
|
+
@diff.removed_slots['slot2'].should == 2
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
it "should report as modified" do
|
|
57
|
+
@diff.should be_different
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it_should_behave_like "Diffing documents"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "Diffing documents with slot changed" do
|
|
66
|
+
before(:each) do
|
|
67
|
+
@store = setup_default_store
|
|
68
|
+
@from = Document.create! :slot1 => 1
|
|
69
|
+
@to = Document.create! :slot1 => 2
|
|
70
|
+
@diff = @to.diff(@from)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should list updated slot" do
|
|
74
|
+
@diff.updated_slots.keys.to_set.should == ['slot1','uuid'].to_set
|
|
75
|
+
@diff.updated_slots['slot1'].should == 2
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
it "should report as modified" do
|
|
80
|
+
@diff.should be_different
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
it_should_behave_like "Diffing documents"
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
['slot_1_diff','default_slot_diff'].each do |strategy|
|
|
90
|
+
describe "Diffing documents with slot changed with slot diffing strategy" do
|
|
91
|
+
before(:each) do
|
|
92
|
+
@store = setup_default_store
|
|
93
|
+
|
|
94
|
+
Object.send!(:remove_const,'Slot1Diff') if defined?(Slot1Diff)
|
|
95
|
+
Slot1Diff = Class.new(SlotDiffStrategy)
|
|
96
|
+
Slot1Diff.should_receive(:diff).with("abcdef","abcdef1").any_number_of_times.and_return("1")
|
|
97
|
+
Slot1Diff.should_receive(:patch).with("abcdef","1").any_number_of_times.and_return("abcdef1")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@meta = Document.create! :diff_strategy_slot1 => strategy # TODO: fix this spec, it willn't care if I say strategy_slot1
|
|
101
|
+
|
|
102
|
+
@from = Document.create! :slot1 => "abcdef", :meta => @meta
|
|
103
|
+
@to = Document.create! :slot1 => "abcdef1", :meta => @meta
|
|
104
|
+
|
|
105
|
+
@diff = @to.diff(@from)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it_should_behave_like "Diffing documents"
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "LamportTimestamp" do
|
|
4
|
+
it "#zero_string" do
|
|
5
|
+
LamportTimestamp.zero_string.should == '000000000000000000000000-0000-0000-0000-000000000000'
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe "Initial LamportTimestamp" do
|
|
10
|
+
before(:each) do
|
|
11
|
+
@t0 = LamportTimestamp.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should have counter == 0" do
|
|
15
|
+
@t0.counter.should == 0
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should have UUID-based uuid" do
|
|
19
|
+
@t0.uuid.should match(UUID_RE)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should pass generated uuid on #next" do
|
|
23
|
+
@t0.next.uuid.should == @t0.uuid
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "shoul return marshal_dump as json" do
|
|
27
|
+
@t0.to_json.should == '"0000000000000000'+@t0.uuid+'"'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
describe "Initial LamportTimestamp with uuid specified" do
|
|
33
|
+
before(:each) do
|
|
34
|
+
@t0 = LamportTimestamp.new(0,NIL_UUID)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should have counter == 0" do
|
|
38
|
+
@t0.counter.should == 0
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should have UUID-based uuid as defined" do
|
|
42
|
+
@t0.uuid.should == NIL_UUID
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should pass uuid on #next" do
|
|
46
|
+
@t0.next.uuid.should == @t0.uuid
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
describe "Preset LamportTimestamp" do
|
|
52
|
+
before(:each) do
|
|
53
|
+
@t0 = LamportTimestamp.new()
|
|
54
|
+
@t123 = LamportTimestamp.new(123)
|
|
55
|
+
@t234 = LamportTimestamp.new(234)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should be compared properly" do
|
|
59
|
+
(@t0 <=> @t123).should == -1
|
|
60
|
+
(@t123 <=> @t234).should == -1
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should have UUID-based uuid" do
|
|
64
|
+
@t123.uuid.should match(UUID_RE)
|
|
65
|
+
@t234.uuid.should match(UUID_RE)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
describe "LamportTimestamp equality" do
|
|
71
|
+
before(:each) do
|
|
72
|
+
@t = LamportTimestamp.new(123)
|
|
73
|
+
@t_dumped = Marshal.dump(@t)
|
|
74
|
+
@t_loaded = Marshal.load(@t_dumped)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Positive
|
|
78
|
+
it { @t.should == @t }
|
|
79
|
+
it { @t.should == @t_loaded }
|
|
80
|
+
it "should correctly compare tons of dumped-loaded timestamps" do
|
|
81
|
+
1000.times do
|
|
82
|
+
t = LamportTimestamp.new(rand(2**64))
|
|
83
|
+
t.should == Marshal.load(Marshal.dump(t))
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Negative
|
|
88
|
+
it { LamportTimestamp.new().should_not == LamportTimestamp.new() }
|
|
89
|
+
it { LamportTimestamp.new(123).should_not == LamportTimestamp.new(123) }
|
|
90
|
+
it { LamportTimestamp.new(234).should_not == LamportTimestamp.new(234) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
describe "Lesser and greater LamportTimestamps" do
|
|
95
|
+
before(:each) do
|
|
96
|
+
@t0 = LamportTimestamp.new()
|
|
97
|
+
@t123 = LamportTimestamp.new(123)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "should be comparable with <" do
|
|
101
|
+
@t0.should < @t123
|
|
102
|
+
@t123.should_not < @t0
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should be comparable with <=" do
|
|
106
|
+
@t0.should <= @t123
|
|
107
|
+
@t123.should <= @t123
|
|
108
|
+
@t123.should_not <= @t0
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should be comparable with >" do
|
|
112
|
+
@t123.should > @t0
|
|
113
|
+
@t123.should_not > @t123
|
|
114
|
+
@t0.should_not > @t123
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "should be comparable with >=" do
|
|
118
|
+
@t123.should >= @t0
|
|
119
|
+
@t123.should >= @t123
|
|
120
|
+
@t0.should_not >= @t123
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it { 1000.times { t = LamportTimestamp.new(rand(2**64)); t.next.next.should > t.next } }
|
|
124
|
+
|
|
125
|
+
it "should generate a list of successive timestamps with next!" do
|
|
126
|
+
t = LamportTimestamp.new(rand(2**32))
|
|
127
|
+
1000.times do
|
|
128
|
+
t_ = t.dup
|
|
129
|
+
t.next!
|
|
130
|
+
t_.should < t
|
|
131
|
+
t_.uuid.should == t.uuid
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
describe "LamportTimestamp maximum counter exception" do
|
|
138
|
+
it "should raise error if counter is too big" do
|
|
139
|
+
lambda { LamportTimestamp.new(2**64 + 1) }.should raise_error(LamportTimestamp::CounterOverflow)
|
|
140
|
+
end
|
|
141
|
+
it "should not raise error if counter is 2**64" do
|
|
142
|
+
lambda { LamportTimestamp.new(2**64) }.should_not raise_error
|
|
143
|
+
lambda { LamportTimestamp.new(2**64-1) }.should_not raise_error
|
|
144
|
+
end
|
|
145
|
+
it "should raise error on LamportTimestamp#next" do
|
|
146
|
+
lambda { LamportTimestamp.new(2**64).next }.should raise_error(LamportTimestamp::CounterOverflow)
|
|
147
|
+
end
|
|
148
|
+
it "should not raise error on LamportTimestamp#next if no overflow occured" do
|
|
149
|
+
lambda { LamportTimestamp.new(2**64 - 1).next }.should_not raise_error
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
describe "LamportTimestamp raw format" do
|
|
155
|
+
before(:each) do
|
|
156
|
+
@t = LamportTimestamp.new(123)
|
|
157
|
+
end
|
|
158
|
+
it "should convert to simple string" do
|
|
159
|
+
@t.to_raw.should == @t.to_s
|
|
160
|
+
end
|
|
161
|
+
it "should correctly convert end-to-end" do
|
|
162
|
+
LamportTimestamp.from_raw(@t.to_raw).should == @t
|
|
163
|
+
end
|
|
164
|
+
it "should compare raw representation exactly like object representation" do
|
|
165
|
+
1000.times do
|
|
166
|
+
t1 = LTS.new(rand(2**32))
|
|
167
|
+
t2 = LTS.new(rand(2**32))
|
|
168
|
+
object_comparison = (t1 <=> t2)
|
|
169
|
+
raw_comparison = (t1.to_raw <=> t2.to_raw)
|
|
170
|
+
object_comparison.should == raw_comparison
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Diffing documents with slot changed and slot's diff strategy is specified on meta" do
|
|
4
|
+
|
|
5
|
+
before(:each) do
|
|
6
|
+
@store = setup_default_store
|
|
7
|
+
Object.send!(:remove_const,'Slot1Diff') if defined?(Slot1Diff)
|
|
8
|
+
Slot1Diff = Class.new(SlotDiffStrategy)
|
|
9
|
+
Slot1Diff.should_receive(:diff).with(1,2).and_return(3)
|
|
10
|
+
|
|
11
|
+
@meta = Document.create! :diff_strategy_slot1 => 'slot_1_diff'
|
|
12
|
+
|
|
13
|
+
@from = Document.create! :slot1 => 1, :meta => @meta
|
|
14
|
+
@to = Document.create! :slot1 => 2, :meta => @meta
|
|
15
|
+
|
|
16
|
+
@diff = @to.diff(@from)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should diff slot value according to its strategy" do
|
|
20
|
+
@diff.updated_slots['slot1'].should == 3
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
describe "Diffing documents with slot changed and slot's diff strategy is specified on meta, but there is no such diff strategy" do
|
|
27
|
+
|
|
28
|
+
before(:each) do
|
|
29
|
+
@store = setup_default_store
|
|
30
|
+
|
|
31
|
+
Object.send!(:remove_const,'Slot1Diff') if defined?(Slot1Diff)
|
|
32
|
+
@meta = Document.create! :diff_strategy_slot1 => 'slot_1_diff'
|
|
33
|
+
|
|
34
|
+
@from = Document.create! :slot1 => 1, :meta => @meta
|
|
35
|
+
@to = Document.create! :slot1 => 2, :meta => @meta
|
|
36
|
+
|
|
37
|
+
@diff = @to.diff(@from)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should not diff slot" do
|
|
41
|
+
@diff.updated_slots['slot1'].should == 2
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "Diffing documents with slot changed and slot's diff strategy is specified on meta, but diff strategy is invalid" do
|
|
47
|
+
|
|
48
|
+
before(:each) do
|
|
49
|
+
@store = setup_default_store
|
|
50
|
+
Object.send!(:remove_const,'Slot1Diff') if defined?(Slot1Diff)
|
|
51
|
+
|
|
52
|
+
Slot1Diff = Class.new
|
|
53
|
+
|
|
54
|
+
@meta = Document.create! :diff_strategy_slot1 => 'slot_1_diff'
|
|
55
|
+
|
|
56
|
+
@from = Document.create! :slot1 => 1, :meta => @meta
|
|
57
|
+
@to = Document.create! :slot1 => 2, :meta => @meta
|
|
58
|
+
|
|
59
|
+
@diff = @to.diff(@from)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should not diff slot" do
|
|
63
|
+
@diff.updated_slots['slot1'].should == 2
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
[DefaultSlotDiff].each do |strategy|
|
|
69
|
+
|
|
70
|
+
describe "#{strategy.name} for String" do
|
|
71
|
+
before(:each) do
|
|
72
|
+
@string1 = "hello world"
|
|
73
|
+
@string2 = "bye world"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should diff to an LCS structure" do
|
|
77
|
+
strategy.diff(@string1, @string2).should be_a_kind_of(Array)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should patch String back" do
|
|
81
|
+
strategy.patch(@string1,strategy.diff(@string1, @string2)).should == @string2
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe "#{strategy.name} for Array" do
|
|
87
|
+
before(:each) do
|
|
88
|
+
@array1 = [1,2,3]
|
|
89
|
+
@array2 = [1,5,3]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should diff to an LCS structure" do
|
|
93
|
+
strategy.diff(@array1, @array2).should be_a_kind_of(Array)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should patch Array back" do
|
|
97
|
+
strategy.patch(@array1,strategy.diff(@array1, @array2)).should == @array2
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe "#{strategy.name} for Hash" do
|
|
102
|
+
before(:each) do
|
|
103
|
+
@hash1 = { :a => 1}
|
|
104
|
+
@hash2 = { :a => 1, :b => 2}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should diff to an LCS structure" do
|
|
108
|
+
strategy.diff(@hash1, @hash2).should be_a_kind_of(Array)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should patch Hash back" do
|
|
112
|
+
strategy.patch(@hash1,strategy.diff(@hash1, @hash2)).should == @hash2
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
describe "#{strategy.name} for document reference" do
|
|
118
|
+
before(:each) do
|
|
119
|
+
@ref1 = "@##{Util.random_uuid}"
|
|
120
|
+
@ref2 = "@##{Util.random_uuid}"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should diff to an LCS structure" do
|
|
124
|
+
strategy.diff(@ref1, @ref2).should be_a_kind_of(String)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should patch document reference back" do
|
|
128
|
+
strategy.patch(@ref1,strategy.diff(@ref1, @ref2)).should == @ref2
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
describe "#{strategy.name} for number" do
|
|
135
|
+
before(:each) do
|
|
136
|
+
@num1 = 1
|
|
137
|
+
@num2 = 2
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "should diff to an LCS structure" do
|
|
141
|
+
strategy.diff(@num1, @num2).should be_a_kind_of(Numeric)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should patch number back" do
|
|
145
|
+
strategy.patch(@num1,strategy.diff(@num1, @num2)).should == @num2
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
describe "#{strategy.name} for different types" do
|
|
150
|
+
before(:each) do
|
|
151
|
+
@val1 = 1
|
|
152
|
+
@val2 = "a"
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "should diff to target value" do
|
|
156
|
+
strategy.diff(@val1, @val2).should == @val2
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should patch number back" do
|
|
160
|
+
strategy.patch(@val1,strategy.diff(@val1, @val2)).should == @val2
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|