public void TestMutabilification() { // Make a single block mutable FVList <int> v = new FVList <int>(0, 1); FWList <int> w = v.ToFWList(); ExpectList(w, 0, 1); w[0] = 2; ExpectList(w, 2, 1); ExpectList(v, 0, 1); // Make another block, make the front block mutable, then the block-of-2 v.Push(-1); w = v.ToFWList(); w[0] = 3; ExpectList(w, 3, 0, 1); Assert.That(w.WithoutFirst(1) == v.WithoutFirst(1)); w[1] = 2; ExpectList(w, 3, 2, 1); Assert.That(w.WithoutFirst(1) != v.WithoutFirst(1)); // Now for a more complicated case: create a long immutable chain by // using a nasty access pattern, add a mutable block in front, then // make some of the immutable blocks mutable. This will cause several // immutable blocks to be consolidated into one mutable block, // shortening the chain. v = new FVList <int>(6); v = v.Add(-1).Tail.Add(5).Add(-1).Tail.Add(4).Add(-1).Tail.Add(3); v = v.Add(-1).Tail.Add(2).Add(-1).Tail.Add(1).Add(-1).Tail.Add(0); ExpectList(v, 0, 1, 2, 3, 4, 5, 6); // At this point, every block in the chain has only one item (it's // a linked list!) and the capacity of each block is 2. Assert.AreEqual(7, v.BlockChainLength); w = v.ToFWList(); w.AddRange(new int[] { 5, 4, 3, 2, 1 }); Assert.AreEqual(w.Count, 12); ExpectList(w, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6); // Indices: 0 1 2 3 4 5 6 7 8 9 10 11 // Blocks: block A | B | C| D| E| F| G| H Assert.AreEqual(8, w.BlockChainLength); Assert.AreEqual(4, w.LocalCount); w[8] = -3; ExpectList(w, 5, 4, 3, 2, 1, 0, 1, 2, -3, 4, 5, 6); // Blocks: block A | block I | F| G| H Assert.AreEqual(5, w.BlockChainLength); }