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");
        }
Exemple #5
0
        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");
        }
Exemple #8
0
        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");
        }
Exemple #12
0
        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");
        }
Exemple #15
0
        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));
        }
Exemple #16
0
        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");
        }
Exemple #19
0
        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");
        }