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.
Files changed (192) hide show
  1. data/README +18 -20
  2. data/bench.html +4001 -0
  3. data/bin/strokedb +14 -0
  4. data/examples/movies.rb +105 -0
  5. data/examples/movies2.rb +97 -0
  6. data/examples/strokewiki/README +28 -0
  7. data/examples/strokewiki/view/edit.xhtml +27 -0
  8. data/examples/strokewiki/view/new.xhtml +26 -0
  9. data/examples/strokewiki/view/pages.xhtml +27 -0
  10. data/examples/strokewiki/view/show.xhtml +40 -0
  11. data/examples/strokewiki/view/versions.xhtml +25 -0
  12. data/examples/strokewiki/wiki.rb +106 -0
  13. data/examples/todo.rb +92 -0
  14. data/lib/strokedb.rb +85 -0
  15. data/lib/{config → strokedb}/config.rb +14 -9
  16. data/lib/strokedb/console.rb +87 -0
  17. data/lib/strokedb/core_ext.rb +10 -0
  18. data/lib/{util/ext → strokedb/core_ext}/blank.rb +1 -1
  19. data/lib/{util/ext → strokedb/core_ext}/enumerable.rb +0 -0
  20. data/lib/{util/ext → strokedb/core_ext}/fixnum.rb +0 -0
  21. data/lib/strokedb/core_ext/float.rb +4 -0
  22. data/lib/{util/ext → strokedb/core_ext}/hash.rb +0 -0
  23. data/lib/strokedb/core_ext/infinity.rb +33 -0
  24. data/lib/strokedb/core_ext/kernel.rb +41 -0
  25. data/lib/strokedb/core_ext/object.rb +16 -0
  26. data/lib/{util/ext → strokedb/core_ext}/string.rb +28 -1
  27. data/lib/strokedb/core_ext/symbol.rb +13 -0
  28. data/lib/strokedb/data_structures.rb +5 -0
  29. data/lib/strokedb/data_structures/chunked_skiplist.rb +123 -0
  30. data/lib/{data_structures → strokedb/data_structures}/inverted_list.rb +0 -0
  31. data/lib/{data_structures → strokedb/data_structures}/point_query.rb +0 -0
  32. data/lib/strokedb/data_structures/simple_skiplist.rb +350 -0
  33. data/lib/{data_structures → strokedb/data_structures}/skiplist.rb +1 -1
  34. data/lib/{document → strokedb}/document.rb +180 -71
  35. data/lib/{document → strokedb/document}/callback.rb +0 -0
  36. data/lib/{document → strokedb/document}/delete.rb +2 -2
  37. data/lib/strokedb/document/dsl.rb +4 -0
  38. data/lib/{document → strokedb/document/dsl}/associations.rb +0 -0
  39. data/lib/{document → strokedb/document/dsl}/coercions.rb +0 -0
  40. data/lib/strokedb/document/dsl/meta_dsl.rb +7 -0
  41. data/lib/{document → strokedb/document/dsl}/validations.rb +26 -21
  42. data/lib/{document → strokedb/document/dsl}/virtualize.rb +0 -0
  43. data/lib/{document → strokedb/document}/meta.rb +92 -29
  44. data/lib/{document → strokedb/document}/slot.rb +17 -5
  45. data/lib/{document → strokedb/document}/util.rb +0 -0
  46. data/lib/{document → strokedb/document}/versions.rb +2 -2
  47. data/lib/strokedb/index.rb +2 -0
  48. data/lib/strokedb/nsurl.rb +24 -0
  49. data/lib/strokedb/store.rb +149 -0
  50. data/lib/strokedb/stores.rb +6 -0
  51. data/lib/{stores → strokedb/stores}/chainable_storage.rb +20 -14
  52. data/lib/strokedb/stores/file_storage.rb +118 -0
  53. data/lib/{stores/inverted_list_index → strokedb/stores}/inverted_list_file_storage.rb +50 -0
  54. data/lib/strokedb/stores/memory_storage.rb +80 -0
  55. data/lib/{stores → strokedb/stores}/remote_store.rb +10 -4
  56. data/lib/strokedb/sync.rb +4 -0
  57. data/lib/{sync → strokedb/sync}/chain_sync.rb +0 -0
  58. data/lib/{sync → strokedb/sync}/diff.rb +12 -1
  59. data/lib/{sync/stroke_diff → strokedb/sync/diff}/array.rb +1 -1
  60. data/lib/{sync/stroke_diff → strokedb/sync/diff}/default.rb +0 -0
  61. data/lib/{sync/stroke_diff → strokedb/sync/diff}/hash.rb +1 -1
  62. data/lib/{sync/stroke_diff → strokedb/sync/diff}/string.rb +1 -1
  63. data/lib/{sync → strokedb/sync}/lamport_timestamp.rb +0 -0
  64. data/lib/{sync → strokedb/sync}/store_sync.rb +15 -7
  65. data/lib/strokedb/transaction.rb +78 -0
  66. data/lib/{util → strokedb}/util.rb +14 -7
  67. data/lib/strokedb/util/attach_dsl.rb +29 -0
  68. data/lib/{util → strokedb/util}/blankslate.rb +0 -0
  69. data/lib/strokedb/util/class_optimization.rb +93 -0
  70. data/lib/{util → strokedb/util}/inflect.rb +0 -0
  71. data/lib/strokedb/util/java_util.rb +13 -0
  72. data/lib/{util → strokedb/util}/lazy_array.rb +0 -0
  73. data/lib/{util → strokedb/util}/lazy_mapping_array.rb +4 -0
  74. data/lib/{util → strokedb/util}/lazy_mapping_hash.rb +0 -0
  75. data/lib/{util → strokedb/util}/serialization.rb +21 -0
  76. data/lib/strokedb/util/uuid.rb +159 -0
  77. data/lib/{util → strokedb/util}/xml.rb +0 -0
  78. data/lib/{view → strokedb}/view.rb +2 -2
  79. data/lib/strokedb/volumes.rb +5 -0
  80. data/lib/strokedb/volumes/archive_volume.rb +165 -0
  81. data/lib/strokedb/volumes/block_volume.rb +169 -0
  82. data/lib/strokedb/volumes/distributed_pointer.rb +43 -0
  83. data/lib/strokedb/volumes/fixed_length_skiplist_volume.rb +109 -0
  84. data/lib/strokedb/volumes/map_volume.rb +268 -0
  85. data/meta/MANIFEST +175 -0
  86. data/script/console +2 -70
  87. data/spec/integration/remote_store_spec.rb +70 -0
  88. data/spec/integration/search_spec.rb +76 -0
  89. data/spec/integration/spec_helper.rb +1 -0
  90. data/spec/lib/spec_helper.rb +1 -0
  91. data/spec/lib/strokedb/config_spec.rb +250 -0
  92. data/spec/lib/strokedb/core_ext/blank_spec.rb +20 -0
  93. data/spec/lib/strokedb/core_ext/extract_spec.rb +42 -0
  94. data/spec/lib/strokedb/core_ext/float_spec.rb +62 -0
  95. data/spec/lib/strokedb/core_ext/infinity_spec.rb +40 -0
  96. data/spec/lib/strokedb/core_ext/spec_helper.rb +1 -0
  97. data/spec/lib/strokedb/core_ext/string_spec.rb +25 -0
  98. data/spec/lib/strokedb/core_ext/symbol_spec.rb +8 -0
  99. data/spec/lib/strokedb/data_structures/chunked_skiplist_spec.rb +144 -0
  100. data/spec/lib/strokedb/data_structures/inverted_list_spec.rb +172 -0
  101. data/spec/lib/strokedb/data_structures/simple_skiplist_spec.rb +200 -0
  102. data/spec/lib/strokedb/data_structures/skiplist_spec.rb +253 -0
  103. data/spec/lib/strokedb/data_structures/spec_helper.rb +1 -0
  104. data/spec/lib/strokedb/document/associations_spec.rb +319 -0
  105. data/spec/lib/strokedb/document/callbacks_spec.rb +134 -0
  106. data/spec/lib/strokedb/document/coercions_spec.rb +110 -0
  107. data/spec/lib/strokedb/document/document_spec.rb +1063 -0
  108. data/spec/lib/strokedb/document/meta_meta_spec.rb +30 -0
  109. data/spec/lib/strokedb/document/meta_spec.rb +435 -0
  110. data/spec/lib/strokedb/document/metaslot_spec.rb +43 -0
  111. data/spec/lib/strokedb/document/slot_spec.rb +130 -0
  112. data/spec/lib/strokedb/document/spec_helper.rb +1 -0
  113. data/spec/lib/strokedb/document/validations_spec.rb +1081 -0
  114. data/spec/lib/strokedb/document/virtualize_spec.rb +80 -0
  115. data/spec/lib/strokedb/nsurl_spec.rb +73 -0
  116. data/spec/lib/strokedb/spec_helper.rb +1 -0
  117. data/spec/lib/strokedb/stores/chained_storages_spec.rb +116 -0
  118. data/spec/lib/strokedb/stores/spec_helper.rb +1 -0
  119. data/spec/lib/strokedb/stores/store_spec.rb +201 -0
  120. data/spec/lib/strokedb/stores/transaction_spec.rb +107 -0
  121. data/spec/lib/strokedb/sync/chain_sync_spec.rb +43 -0
  122. data/spec/lib/strokedb/sync/diff_spec.rb +111 -0
  123. data/spec/lib/strokedb/sync/lamport_timestamp_spec.rb +174 -0
  124. data/spec/lib/strokedb/sync/slot_diff_spec.rb +164 -0
  125. data/spec/lib/strokedb/sync/spec_helper.rb +1 -0
  126. data/spec/lib/strokedb/sync/store_sync_spec.rb +181 -0
  127. data/spec/lib/strokedb/sync/stroke_diff/array_spec.rb +97 -0
  128. data/spec/lib/strokedb/sync/stroke_diff/complex_spec.rb +58 -0
  129. data/spec/lib/strokedb/sync/stroke_diff/hash_spec.rb +144 -0
  130. data/spec/lib/strokedb/sync/stroke_diff/scalar_spec.rb +23 -0
  131. data/spec/lib/strokedb/sync/stroke_diff/spec_helper.rb +25 -0
  132. data/spec/lib/strokedb/sync/stroke_diff/string_spec.rb +61 -0
  133. data/spec/lib/strokedb/util/attach_dsl_spec.rb +45 -0
  134. data/spec/lib/strokedb/util/inflect_spec.rb +14 -0
  135. data/spec/lib/strokedb/util/lazy_array_spec.rb +157 -0
  136. data/spec/lib/strokedb/util/lazy_mapping_array_spec.rb +174 -0
  137. data/spec/lib/strokedb/util/lazy_mapping_hash_spec.rb +92 -0
  138. data/spec/lib/strokedb/util/spec_helper.rb +1 -0
  139. data/spec/lib/strokedb/util/uuid_spec.rb +46 -0
  140. data/spec/lib/strokedb/view_spec.rb +228 -0
  141. data/spec/lib/strokedb/volumes/archive_volume_spec.rb +105 -0
  142. data/spec/lib/strokedb/volumes/block_volume_spec.rb +100 -0
  143. data/spec/lib/strokedb/volumes/distributed_pointer_spec.rb +14 -0
  144. data/spec/lib/strokedb/volumes/fixed_length_skiplist_volume_spec.rb +177 -0
  145. data/spec/lib/strokedb/volumes/map_volume_spec.rb +172 -0
  146. data/spec/lib/strokedb/volumes/spec_helper.rb +1 -0
  147. data/spec/regression/docref_spec.rb +94 -0
  148. data/spec/regression/meta_spec.rb +23 -0
  149. data/spec/regression/spec_helper.rb +1 -0
  150. data/spec/regression/sync_spec.rb +36 -0
  151. data/spec/spec.opts +7 -0
  152. data/spec/spec_helper.rb +37 -0
  153. data/spec/temp/storages/TIMESTAMP +1 -0
  154. data/spec/temp/storages/UUID +1 -0
  155. data/spec/temp/storages/database-sync/TIMESTAMP +1 -0
  156. data/spec/temp/storages/database-sync/UUID +1 -0
  157. data/spec/temp/storages/database-sync/config +1 -0
  158. data/spec/temp/storages/database-sync/file/LAST +1 -0
  159. data/spec/temp/storages/database-sync/file/bd/f6/bdf675e5-8a7b-494e-97f2-f74a14ccd95d.av +0 -0
  160. data/spec/temp/storages/database-sync/file/uindex.wal +0 -0
  161. data/spec/temp/storages/database-sync/inverted_list_file/INVERTED_INDEX +1 -0
  162. data/spec/temp/storages/inverted_list_storage/INVERTED_INDEX +0 -0
  163. data/strokedb.gemspec +120 -0
  164. data/task/benchmark.task +9 -0
  165. data/task/ditz.task +30 -0
  166. data/task/echoe.rb +17 -0
  167. data/task/rcov.task +50 -0
  168. data/task/rdoc.task +10 -0
  169. data/task/rspec.task +0 -0
  170. data/vendor/java_inline.rb +106 -0
  171. data/vendor/rbmodexcl/mrimodexcl.rb +82 -0
  172. data/vendor/rbmodexcl/rbmodexcl.rb +5 -0
  173. data/vendor/rbmodexcl/rbxmodexcl.rb +48 -0
  174. data/vendor/rbmodexcl/spec/unextend_spec.rb +50 -0
  175. data/vendor/rbmodexcl/spec/uninclude_spec.rb +26 -0
  176. metadata +271 -79
  177. data/CONTRIBUTORS +0 -7
  178. data/CREDITS +0 -13
  179. data/bin/sdbc +0 -2
  180. data/lib/init.rb +0 -57
  181. data/lib/stores/inverted_list_index/inverted_list_index.rb +0 -49
  182. data/lib/stores/skiplist_store/chunk.rb +0 -119
  183. data/lib/stores/skiplist_store/chunk_storage.rb +0 -21
  184. data/lib/stores/skiplist_store/file_chunk_storage.rb +0 -44
  185. data/lib/stores/skiplist_store/memory_chunk_storage.rb +0 -37
  186. data/lib/stores/skiplist_store/skiplist_store.rb +0 -217
  187. data/lib/stores/store.rb +0 -5
  188. data/lib/sync/stroke_diff/stroke_diff.rb +0 -9
  189. data/lib/util/ext/object.rb +0 -8
  190. data/lib/util/java_util.rb +0 -9
  191. data/lib/util/trigger_partition.rb +0 -136
  192. 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