public void ItemTree_Basic() { byte[] byteBuffer = new byte[100]; int[] intBuffer = new int[10]; String8Set splitPath8; StringStore strings = new StringStore(); ItemTree fileTree = new ItemTree(); string[] filePaths = { @"C:\Code\Arriba\Arriba\Diagnostics\DailyLogTraceListener.cs", @"C:\Code\Arriba\Arriba\Diagnostics\ProgressWriter.cs", @"C:\Code\Arriba\Arriba\Diagnostics\Log4NetDiagnosticConsumer.cs", @"C:\Code\Arriba\Arriba\Diagnostics\Memory.cs", @"C:\Code\Arriba\Arriba\Diagnostics\TraceWriter.cs" }; List <int> fileTreeIndexes = new List <int>(); // Index each file path foreach (string filePath in filePaths) { splitPath8 = String8.Convert(filePath, byteBuffer).Split('\\', intBuffer); fileTreeIndexes.Add(fileTree.AddPath(0, splitPath8, strings)); } for (int i = 0; i < filePaths.Length; ++i) { // Reconstruct each file path and confirm they match string rebuiltPath = fileTree.GetPath(fileTreeIndexes[i], strings, '\\').ToString(); Assert.AreEqual(filePaths[i], rebuiltPath); // Verify find by path works splitPath8 = String8.Convert(filePaths[i], byteBuffer).Split('\\', intBuffer); int foundAtIndex; Assert.IsTrue(fileTree.TryFindByPath(0, splitPath8, strings, out foundAtIndex)); Assert.AreEqual(fileTreeIndexes[i], foundAtIndex); } // Verify find works int foundIndex; // Root found under sentinel root Assert.IsTrue(fileTree.TryFindChildByName(0, strings.FindOrAddString("C:"), out foundIndex)); Assert.AreEqual(1, foundIndex); // Root not found under another node Assert.IsFalse(fileTree.TryFindChildByName(1, strings.FindOrAddString("C:"), out foundIndex)); // Node not found at root Assert.IsFalse(fileTree.TryFindChildByName(0, strings.FindOrAddString("Code"), out foundIndex)); // Node found under the right parent Assert.IsTrue(fileTree.TryFindChildByName(1, strings.FindOrAddString("Code"), out foundIndex)); Assert.AreEqual(2, foundIndex); // FindByPath works under a partial path splitPath8 = String8.Convert(@"Code\Arriba", byteBuffer).Split('\\', intBuffer); int arribaIndex; Assert.IsTrue(fileTree.TryFindByPath(1, splitPath8, strings, out arribaIndex)); splitPath8 = String8.Convert(@"Arriba\Diagnostics\DailyLogTraceListener.cs", byteBuffer).Split('\\', intBuffer); int dailyLogIndex; Assert.IsTrue(fileTree.TryFindByPath(arribaIndex, splitPath8, strings, out dailyLogIndex)); Assert.AreEqual(fileTreeIndexes[0], dailyLogIndex); // FindByPath returns the closest element when it fails splitPath8 = String8.Convert(@"C:\Nope", byteBuffer).Split('\\', intBuffer); int nopeIndex; Assert.IsFalse(fileTree.TryFindByPath(0, splitPath8, strings, out nopeIndex)); Assert.AreEqual(1, nopeIndex, @"Failed find for C:\Nope should return 'C:' index; the successful portion of the search."); splitPath8 = String8.Convert(@"C:\Code\Arriba\Arriba\Diagnostics\TraceWriter.cs\Nope", byteBuffer).Split('\\', intBuffer); Assert.IsFalse(fileTree.TryFindByPath(0, splitPath8, strings, out nopeIndex)); Assert.AreEqual(fileTreeIndexes[4], nopeIndex); // Verify depth works Assert.AreEqual(0, fileTree.GetDepth(0)); Assert.AreEqual(1, fileTree.GetDepth(1)); Assert.AreEqual(6, fileTree.GetDepth(fileTreeIndexes[0])); Assert.AreEqual("C:", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 1))].ToString()); Assert.AreEqual("Code", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 2))].ToString()); Assert.AreEqual("Arriba", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 3))].ToString()); Assert.AreEqual("Arriba", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 4))].ToString()); // Sort the tree by name fileTree.SortByName(strings); // Log the tree Trace.WriteLine(Write.ToString((w) => fileTree.WriteTree(w, strings, 1))); // Verify roundtrip ItemTree readTree = new ItemTree(); Verify.RoundTrip(fileTree, readTree); fileTree = readTree; // Reconstruct each file path for (int i = 0; i < filePaths.Length; ++i) { string rebuiltPath = fileTree.GetPath(fileTreeIndexes[i], strings, '\\').ToString(); Assert.AreEqual(filePaths[i], rebuiltPath); } }