public void ReplicatedDataSerializer_should_serialize_ORDictionary_delta() { CheckSerialization(ORDictionary <string, GSet <string> > .Empty .SetItem(_address1, "a", GSet.Create("A")) .SetItem(_address2, "b", GSet.Create("B")) .Delta); CheckSerialization(ORDictionary <string, GSet <string> > .Empty .SetItem(_address1, "a", GSet.Create("A")) .ResetDelta() .Remove(_address2, "a") .Delta); CheckSerialization(ORDictionary <string, GSet <string> > .Empty .SetItem(_address1, "a", GSet.Create("A")) .Remove(_address2, "a") .Delta); CheckSerialization(ORDictionary <string, ORSet <string> > .Empty .SetItem(_address1, "a", ORSet.Create(_address1, "A")) .SetItem(_address2, "b", ORSet.Create(_address2, "B")) .AddOrUpdate(_address1, "a", ORSet <string> .Empty, old => old.Add(_address1, "C")) .Delta); CheckSerialization(ORDictionary <string, ORSet <string> > .Empty .ResetDelta() .AddOrUpdate(_address1, "a", ORSet <string> .Empty, old => old.Add(_address1, "C")) .Delta); }
public void ORDictionary_must_not_have_anomalies_for_remove_with_update_scenario_and_deltas_9() { var m1 = ORDictionary.Create(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")) .SetItem(_node2, "b", GSet.Create("B")); var m2 = ORDictionary.Create(_node2, "c", GSet.Create("C")); var merged1 = m1.Merge(m2); var m3 = merged1.ResetDelta().Remove(_node1, "b").Remove(_node2, "b"); var m4 = merged1.ResetDelta() .AddOrUpdate(_node2, "b", GSet <string> .Empty, x => x.Add("B2")) .AddOrUpdate(_node2, "b", GSet <string> .Empty, x => x.Add("B3")); var merged2 = m3.Merge(m4); merged2.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged2.Entries["b"].Elements.Should().BeEquivalentTo("B2", "B3"); merged2.Entries["c"].Elements.Should().BeEquivalentTo("C"); var merged3 = merged1.MergeDelta(m3.Delta).MergeDelta(m4.Delta); merged3.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged3.Entries["b"].Elements.Should().BeEquivalentTo("B2", "B3"); merged3.Entries["c"].Elements.Should().BeEquivalentTo("C"); }
public void ORDictionary_must_work_with_deltas_and_Add_for_GSet_elements_type() { var m1 = ORDictionary.Create(_node1, "a", GSet.Create("A")); var m2 = m1.ResetDelta().AddOrUpdate(_node1, "a", GSet <string> .Empty, x => x.Add("B")); var m3 = ORDictionary <string, GSet <string> > .Empty.MergeDelta(m1.Delta).MergeDelta(m2.Delta); m3.Entries["a"].Should().BeEquivalentTo("A", "B"); }
public void ORDictionary_must_be_able_to_remove_entries() { var m = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")) .Remove(_node1, "a"); m.Entries.Keys.Should().NotContain("a"); m.Entries.Keys.Should().Contain("b"); }
public void A_ORDictionary_should_be_able_to_remove_entries() { var m = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")) .Remove(_node1, "a"); Assert.DoesNotContain("a", m.Entries.Keys); Assert.Contains("b", m.Entries.Keys); }
public void ORDictionary_must_not_have_anomalies_for_remove_with_update_scenario_and_deltas_11() { var m1 = ORDictionary.Create(_node1, "a", GSet.Create("A")); var m2 = ORDictionary.Create(_node2, "a", GSet <string> .Empty).Remove(_node2, "a"); var merged1 = m1.Merge(m2); merged1.Entries["a"].Elements.Should().BeEquivalentTo("A"); var merged2 = m1.MergeDelta(m2.Delta); merged2.Entries["a"].Elements.Should().BeEquivalentTo("A"); }
public void ORDictionary_must_be_able_to_add_entries() { var m = ORDictionary.Create( Tuple.Create(_node1, "a", GSet.Create("A")), Tuple.Create(_node1, "b", GSet.Create("B"))); m["a"].Elements.Should().BeEquivalentTo("A"); m["b"].Elements.Should().BeEquivalentTo("B"); var m2 = m.SetItem(_node1, "a", GSet.Create("C")); m2.Entries["a"].Elements.Should().BeEquivalentTo("C"); }
public void A_ORDictionary_should_be_able_to_add_entries() { var m = ORDictionary.Create( Tuple.Create(_node1, "a", GSet.Create("A")), Tuple.Create(_node1, "b", GSet.Create("B"))); Assert.Equal(ImmutableHashSet.Create("A"), m["a"].Elements); Assert.Equal(ImmutableHashSet.Create("B"), m["b"].Elements); var m2 = m.SetItem(_node1, "a", GSet.Create("C")); Assert.Equal(ImmutableHashSet.Create("C"), m2.Entries["a"].Elements); }
public void ReplicatedDataSerializer_should_serialize_GSet() { CheckSerialization(GSet <string> .Empty); CheckSerialization(GSet.Create("a")); CheckSerialization(GSet.Create("a", "b")); CheckSerialization(GSet.Create(1, 2, 3)); CheckSerialization(GSet.Create(_address1, _address2)); CheckSerialization(GSet.Create <object>(1L, "2", 3, _address1)); CheckSameContent(GSet.Create("a", "b"), GSet.Create("a", "b")); CheckSameContent(GSet.Create("a", "b"), GSet.Create("b", "a")); CheckSameContent(GSet.Create(_address1, _address2, _address3), GSet.Create(_address2, _address1, _address3)); CheckSameContent(GSet.Create(_address1, _address2, _address3), GSet.Create(_address3, _address2, _address1)); }
public void ORDictionary_must_be_able_to_add_entries_with_delta() { var m = ORDictionary.Create( Tuple.Create(_node1, "a", GSet.Create("A")), Tuple.Create(_node1, "b", GSet.Create("B"))); var md = m.Delta; var m1 = ORDictionary <string, GSet <string> > .Empty.MergeDelta(md); m1.Entries["a"].Should().BeEquivalentTo("A"); m1.Entries["b"].Should().BeEquivalentTo("B"); var m2 = m1.SetItem(_node1, "a", GSet.Create("C")); m2.Entries["a"].Should().BeEquivalentTo("C"); }
public void ORDictionary_must_illustrate_the_danger_of_using_Remove_then_Add_to_replace_an_entry() { var m1 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")); var m2 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node2, "c", GSet.Create("C")); var merged1 = m1.Merge(m2); var m3 = merged1.Remove(_node1, "b").SetItem(_node1, "b", GSet.Create("B2")); var merged2 = merged1.Merge(m3); merged2["a"].Elements.Should().BeEquivalentTo("A"); merged2["b"].Elements.Should().BeEquivalentTo("B", "B2"); merged2["c"].Elements.Should().BeEquivalentTo("C"); }
public void A_ORDictionary_should_illustrate_the_danger_of_using_Remove_then_Add_to_replace_an_entry() { var m1 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")); var m2 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node2, "c", GSet.Create("C")); var merged1 = m1.Merge(m2); var m3 = merged1.Remove(_node1, "b").SetItem(_node1, "b", GSet.Create("B2")); var merged2 = merged1.Merge(m3); Assert.Equal(ImmutableHashSet.Create("A"), merged2["a"].Elements); Assert.Equal(ImmutableHashSet.Create("B", "B2"), merged2["b"].Elements); Assert.Equal(ImmutableHashSet.Create("C"), merged2["c"].Elements); }
public void ORDictionary_must_be_able_to_remove_entry_using_a_delta() { var m = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")); var addDelta = m.Delta; var removeDelta = m.ResetDelta().RemoveKey(_node1, "a").Delta; var m1 = ORDictionary <string, GSet <string> > .Empty.MergeDelta(addDelta); m1.Entries.Keys.Should().Contain("a"); var m2 = m1.MergeDelta(removeDelta); m2.Entries.Keys.Should().NotContain("a"); m2.Entries.Keys.Should().Contain("b"); }
public void ORDictionary_must_be_able_to_have_its_entries_correctly_merged_with_another_ORDictionary_with_other_entries() { var m1 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A")) .SetItem(_node1, "b", GSet.Create("B")); var m2 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node2, "c", GSet.Create("C")); // merge both ways var merged1 = m1.Merge(m2); merged1.Entries.Keys.Should().Contain("a"); merged1.Entries.Keys.Should().Contain("b"); merged1.Entries.Keys.Should().Contain("c"); var merged2 = m2.Merge(m1); merged2.Entries.Keys.Should().Contain("a"); merged2.Entries.Keys.Should().Contain("b"); merged2.Entries.Keys.Should().Contain("c"); }
public void ReplicatorMessageSerializer_should_serialize_Replicator_message() { var ref1 = Sys.ActorOf(Props.Empty, "ref1"); var data1 = GSet.Create("a"); CheckSerialization(new Get(_keyA, ReadLocal.Instance)); CheckSerialization(new Get(_keyA, new ReadMajority(TimeSpan.FromSeconds(2)), "x")); CheckSerialization(new GetSuccess(_keyA, null, data1)); CheckSerialization(new GetSuccess(_keyA, "x", data1)); CheckSerialization(new NotFound(_keyA, "x")); CheckSerialization(new GetFailure(_keyA, "x")); CheckSerialization(new Subscribe(_keyA, ref1)); CheckSerialization(new Unsubscribe(_keyA, ref1)); CheckSerialization(new Changed(_keyA, data1)); CheckSerialization(new DataEnvelope(data1)); CheckSerialization(new DataEnvelope(data1, ImmutableDictionary.CreateRange(new Dictionary <UniqueAddress, IPruningState> { { _address1, new PruningPerformed(DateTime.UtcNow) }, { _address3, new PruningInitialized(_address2, _address1.Address) }, }))); CheckSerialization(new Write("A", new DataEnvelope(data1))); CheckSerialization(WriteAck.Instance); CheckSerialization(new Read("A")); CheckSerialization(new ReadResult(new DataEnvelope(data1))); CheckSerialization(new ReadResult(null)); CheckSerialization(new Internal.Status(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <string, ByteString>("A", ByteString.CopyFromUtf8("a")), new KeyValuePair <string, ByteString>("B", ByteString.CopyFromUtf8("b")), }), 3, 10)); CheckSerialization(new Gossip(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <string, DataEnvelope>("A", new DataEnvelope(data1)), new KeyValuePair <string, DataEnvelope>("B", new DataEnvelope(GSet.Create("b").Add("b"))), }), true)); }
public void A_ORDictionary_should_be_able_to_have_its_entries_correctly_merged_with_another_ORDictionary_with_overlaping_entries() { var m1 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A1")) .SetItem(_node1, "b", GSet.Create("B1")) .Remove(_node1, "a") .SetItem(_node1, "d", GSet.Create("D1")); var m2 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node2, "c", GSet.Create("C2")) .SetItem(_node2, "a", GSet.Create("A2")) .SetItem(_node2, "b", GSet.Create("B2")) .Remove(_node2, "b") .SetItem(_node2, "d", GSet.Create("D2")); // merge both ways var merged1 = m1.Merge(m2); Assert.Contains("a", merged1.Entries.Keys); Assert.Equal(ImmutableHashSet.Create("A2"), merged1["a"].Elements); Assert.Contains("b", merged1.Entries.Keys); Assert.Equal(ImmutableHashSet.Create("B1"), merged1["b"].Elements); Assert.Contains("c", merged1.Entries.Keys); Assert.Contains("d", merged1.Entries.Keys); Assert.Equal(ImmutableHashSet.Create("D1", "D2"), merged1["d"].Elements); var merged2 = m2.Merge(m1); Assert.Contains("a", merged2.Entries.Keys); Assert.Equal(ImmutableHashSet.Create("A2"), merged2["a"].Elements); Assert.Contains("b", merged2.Entries.Keys); Assert.Equal(ImmutableHashSet.Create("B1"), merged2["b"].Elements); Assert.Contains("c", merged2.Entries.Keys); Assert.Contains("d", merged2.Entries.Keys); Assert.Equal(ImmutableHashSet.Create("D1", "D2"), merged2["d"].Elements); }
public void ORDictionary_must_be_able_to_have_its_entries_correctly_merged_with_another_ORDictionary_with_overlaping_entries() { var m1 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node1, "a", GSet.Create("A1")) .SetItem(_node1, "b", GSet.Create("B1")) .Remove(_node1, "a") .SetItem(_node1, "d", GSet.Create("D1")); var m2 = ORDictionary <string, GSet <string> > .Empty .SetItem(_node2, "c", GSet.Create("C2")) .SetItem(_node2, "a", GSet.Create("A2")) .SetItem(_node2, "b", GSet.Create("B2")) .Remove(_node2, "b") .SetItem(_node2, "d", GSet.Create("D2")); // merge both ways var merged1 = m1.Merge(m2); merged1.Entries.Keys.Should().Contain("a"); merged1["a"].Elements.Should().BeEquivalentTo("A2"); merged1.Entries.Keys.Should().Contain("b"); merged1["b"].Elements.Should().BeEquivalentTo("B1"); merged1.Entries.Keys.Should().Contain("c"); merged1.Entries.Keys.Should().Contain("d"); merged1["d"].Elements.Should().BeEquivalentTo("D1", "D2"); var merged2 = m2.Merge(m1); merged2.Entries.Keys.Should().Contain("a"); merged2["a"].Elements.Should().BeEquivalentTo("A2"); merged2.Entries.Keys.Should().Contain("b"); merged2["b"].Elements.Should().BeEquivalentTo("B1"); merged2.Entries.Keys.Should().Contain("c"); merged2.Entries.Keys.Should().Contain("d"); merged2["d"].Elements.Should().BeEquivalentTo("D1", "D2"); }
public void ORDictionary_must_not_have_anomalies_for_remove_with_update_scenario_and_deltas_5() { var m1 = ORDictionary.Create(_node1, "a", GSet.Create("A")).SetItem(_node1, "b", GSet.Create("B")); var m2 = ORDictionary.Create(_node2, "c", GSet.Create("C")); var merged1 = m1.Merge(m2); var m3 = merged1.ResetDelta().Remove(_node1, "b"); var m4 = merged1.ResetDelta().SetItem(_node2, "b", GSet <string> .Empty.Add("B2")); var merged2 = m3.Merge(m4); merged2.Entries["a"].Elements.Should().BeEquivalentTo("A"); // note that B is not included, because it was removed in both timelines merged2.Entries["b"].Elements.Should().BeEquivalentTo("B2"); merged2.Entries["c"].Elements.Should().BeEquivalentTo("C"); var merged3 = m3.MergeDelta(m4.Delta); merged3.Entries["a"].Elements.Should().BeEquivalentTo("A"); // note that B is not included, because it was removed in both timelines merged3.Entries["b"].Elements.Should().BeEquivalentTo("B2"); merged3.Entries["c"].Elements.Should().BeEquivalentTo("C"); }
public void ReplicatorMessageSerializer_should_serialize_Replicator_message() { var ref1 = Sys.ActorOf(Props.Empty, "ref1"); var data1 = GSet.Create("a"); var delta1 = GCounter.Empty.Increment(_address1, 17).Increment(_address2, 2).Delta; var delta2 = delta1.Increment(_address2, 1).Delta; var delta3 = ORSet <string> .Empty.Add(_address1, "a").Delta; var delta4 = ORMultiValueDictionary <string, string> .Empty.AddItem(_address1, "a", "b").Delta; CheckSerialization(new Get(_keyA, ReadLocal.Instance)); CheckSerialization(new Get(_keyA, new ReadMajority(TimeSpan.FromSeconds(2)), "x")); CheckSerialization(new Get(_keyA, new ReadMajority(TimeSpan.FromMilliseconds(((double)int.MaxValue) + 50)), "x")); CheckSerialization(new Get(_keyA, new ReadMajority(TimeSpan.FromSeconds(2), 3), "x")); _serializer.Invoking(s => { s.ToBinary(new Get(_keyA, new ReadMajority(TimeSpan.FromMilliseconds(((double)int.MaxValue) * 3)), "x")); }) .ShouldThrow <ArgumentOutOfRangeException>("Our protobuf protocol does not support timeouts larger than unsigned ints") .Which.Message.Contains("unsigned int"); CheckSerialization(new GetSuccess(_keyA, null, data1)); CheckSerialization(new GetSuccess(_keyA, "x", data1)); CheckSerialization(new NotFound(_keyA, "x")); CheckSerialization(new GetFailure(_keyA, "x")); CheckSerialization(new Subscribe(_keyA, ref1)); CheckSerialization(new Unsubscribe(_keyA, ref1)); CheckSerialization(new Changed(_keyA, data1)); CheckSerialization(new DataEnvelope(data1)); CheckSerialization(new DataEnvelope(data1, ImmutableDictionary.CreateRange(new Dictionary <UniqueAddress, IPruningState> { { _address1, new PruningPerformed(DateTime.UtcNow) }, { _address3, new PruningInitialized(_address2, _address1.Address) }, }))); CheckSerialization(new Write("A", new DataEnvelope(data1), _address1)); CheckSerialization(WriteAck.Instance); CheckSerialization(WriteNack.Instance); CheckSerialization(DeltaNack.Instance); CheckSerialization(new Read("A", _address1)); CheckSerialization(new ReadResult(new DataEnvelope(data1))); CheckSerialization(new ReadResult(null)); CheckSerialization(new Internal.Status(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <string, ByteString>("A", ByteString.CopyFromUtf8("a")), new KeyValuePair <string, ByteString>("B", ByteString.CopyFromUtf8("b")), }), 3, 10, 17, 19)); CheckSerialization(new Internal.Status(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <string, ByteString>("A", ByteString.CopyFromUtf8("a")), new KeyValuePair <string, ByteString>("B", ByteString.CopyFromUtf8("b")), }), 3, 10, null, 19)); // (from scala code) can be None when sending back to a node of version 2.5.21 CheckSerialization(new Gossip(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <string, DataEnvelope>("A", new DataEnvelope(data1)), new KeyValuePair <string, DataEnvelope>("B", new DataEnvelope(GSet.Create("b").Add("c"))), }), true, 17, 19)); CheckSerialization(new Gossip(ImmutableDictionary.CreateRange(new[] { new KeyValuePair <string, DataEnvelope>("A", new DataEnvelope(data1)), new KeyValuePair <string, DataEnvelope>("B", new DataEnvelope(GSet.Create("b").Add("c"))), }), true, null, 19)); // (from scala code) can be None when sending back to a node of version 2.5.21 CheckSerialization(new DeltaPropagation(_address1, true, ImmutableDictionary.CreateRange(new Dictionary <string, Delta> { { "A", new Delta(new DataEnvelope(delta1), 1, 1) }, { "B", new Delta(new DataEnvelope(delta2), 3, 5) }, { "C", new Delta(new DataEnvelope(delta3), 1, 1) }, { "DC", new Delta(new DataEnvelope(delta4), 1, 1) } }))); CheckSerialization(new DurableDataEnvelope(data1)); var pruning = ImmutableDictionary.CreateRange(new Dictionary <UniqueAddress, IPruningState> { { _address1, new PruningPerformed(DateTime.UtcNow) }, { _address3, new PruningInitialized(_address2, _address1.Address) }, }); var deserializedDurableDataEnvelope = CheckSerialization( new DurableDataEnvelope(new DataEnvelope(data1, pruning, new SingleVersionVector(_address1, 13)))); var expectedPruning = pruning .Where(kvp => kvp.Value is PruningPerformed) .ToDictionary(k => k.Key, v => v.Value); deserializedDurableDataEnvelope.DataEnvelope.Pruning.ShouldAllBeEquivalentTo(expectedPruning); deserializedDurableDataEnvelope.DataEnvelope.DeltaVersions.Count.Should().Be(0); }
public void ReplicatedDataSerializer_should_serialize_ORDictionary() { CheckSerialization(ORDictionary <string, GSet <string> > .Empty); CheckSerialization(ORDictionary <string, GSet <string> > .Empty.SetItem(_address1, "a", GSet.Create("A"))); CheckSerialization(ORDictionary <IActorRef, GSet <string> > .Empty.SetItem(_address1, TestActor, GSet.Create("A"))); CheckSerialization(ORDictionary <string, GSet <string> > .Empty.SetItem(_address1, "a", GSet.Create("A")).SetItem(_address2, "b", GSet.Create("B"))); }
public void ORDictionary_must_do_not_have_divergence_in_dot_versions_between_the_underlying_map_and_ORDictionary_delta() { var m1 = ORDictionary <string, GSet <string> > .Empty.SetItem(_node1, "a", GSet.Create("A")); var deltaVersion = default(long?); var delta = m1.Delta as ORDictionary <string, GSet <string> > .PutDeltaOperation; if (delta != null) { VersionVector v; var addDelta = delta.Underlying as ORSet <string> .AddDeltaOperation; if (addDelta != null && addDelta.Underlying.ElementsMap.TryGetValue("a", out v)) { deltaVersion = v.VersionAt(_node1); } } VersionVector v2; var fullVersion = !m1.KeySet.ElementsMap.TryGetValue("a", out v2) ? default(long?) : v2.VersionAt(_node1); deltaVersion.Should().Be(fullVersion); }
public void ORDictionary_must_work_with_delta_coalescing_scenario_1() { var m1 = ORDictionary.Create(_node1, "a", GSet.Create("A")).SetItem(_node1, "b", GSet.Create("B")); var m2 = m1.ResetDelta() .SetItem(_node2, "b", GSet.Create("B2")) .AddOrUpdate(_node2, "b", GSet <string> .Empty, x => x.Add("B3")); var merged1 = m1.Merge(m2); merged1.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged1.Entries["b"].Elements.Should().BeEquivalentTo("B", "B2", "B3"); var merged2 = m1.MergeDelta(m2.Delta); merged2.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged2.Entries["b"].Elements.Should().BeEquivalentTo("B", "B2", "B3"); var m3 = ORDictionary.Create(_node1, "a", GSet.Create("A")).SetItem(_node2, "b", GSet.Create("B")); var m4 = m3.ResetDelta().SetItem(_node2, "b", GSet.Create("B2")).SetItem(_node2, "b", GSet.Create("B3")); var merged3 = m3.Merge(m4); merged3.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged3.Entries["b"].Elements.Should().BeEquivalentTo("B", "B3"); var merged4 = m3.MergeDelta(m4.Delta); merged4.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged4.Entries["b"].Elements.Should().BeEquivalentTo("B", "B3"); var m5 = ORDictionary.Create(_node1, "a", GSet.Create("A")).SetItem(_node2, "b", GSet.Create("B")); var m6 = m5.ResetDelta() .SetItem(_node2, "b", GSet.Create("B2")) .AddOrUpdate(_node2, "b", GSet <string> .Empty, x => x.Add("B3")) .AddOrUpdate(_node2, "b", GSet <string> .Empty, x => x.Add("B4")); var merged5 = m5.Merge(m6); merged5.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged5.Entries["b"].Elements.Should().BeEquivalentTo("B", "B2", "B3", "B4"); var merged6 = m5.MergeDelta(m6.Delta); merged6.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged6.Entries["b"].Elements.Should().BeEquivalentTo("B", "B2", "B3", "B4"); var m7 = ORDictionary.Create(_node1, "a", GSet.Create("A")).SetItem(_node2, "b", GSet.Create("B")); var m8 = m7.ResetDelta() .SetItem(_node2, "b", GSet.Create("B2")) .SetItem(_node2, "d", GSet.Create("D")) .SetItem(_node2, "b", GSet.Create("B3")); var merged7 = m7.Merge(m8); merged7.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged7.Entries["b"].Elements.Should().BeEquivalentTo("B", "B3"); merged7.Entries["d"].Elements.Should().BeEquivalentTo("D"); var merged8 = m7.MergeDelta(m8.Delta); merged8.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged8.Entries["b"].Elements.Should().BeEquivalentTo("B", "B3"); merged8.Entries["d"].Elements.Should().BeEquivalentTo("D"); var m9 = ORDictionary.Create(_node1, "a", GSet.Create("A")).SetItem(_node2, "b", GSet.Create("B")); var m10 = m9.ResetDelta() .SetItem(_node2, "b", GSet.Create("B2")) .SetItem(_node2, "d", GSet.Create("D")) .Remove(_node2, "d") .SetItem(_node2, "b", GSet.Create("B3")); var merged9 = m9.Merge(m10); merged9.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged9.Entries["b"].Elements.Should().BeEquivalentTo("B", "B3"); var merged10 = m9.MergeDelta(m10.Delta); merged10.Entries["a"].Elements.Should().BeEquivalentTo("A"); merged10.Entries["b"].Elements.Should().BeEquivalentTo("B", "B3"); }