public void ExceptionOnNullChildren() { var root = new ConfigEnvironmentKeyPath("Foo"); var child = new ConfigEnvironmentKeyPath("Bar", root); Assert.NotNull(child.FullPath); }
public void CreateNew() { var path = new ConfigEnvironmentKeyPath(""); Assert.Empty(path.Children); Assert.Equal("", path.FullPath); Assert.Null(path.Parent); Assert.Equal("", path.Path); }
public void FullPathResolution() { // setup hierarchy var root = new ConfigEnvironmentKeyPath("Foo"); var bar = new ConfigEnvironmentKeyPath("Bar", root); var baz = new ConfigEnvironmentKeyPath("Baz", bar); var jar = new ConfigEnvironmentKeyPath("Jar", root); root.Children.AddRange(new[] { bar, jar }); bar.Children.Add(baz); // actual tests // no trailing / because no children Assert.Equal("Foo/Jar", jar.FullPath); Assert.Equal("Foo/Bar/Baz", baz.FullPath); // trailing / because of children Assert.Equal("Foo/Bar/", bar.FullPath); Assert.Equal("Foo/", root.FullPath); }
public void ExceptionOnNullParent() { var child = new ConfigEnvironmentKeyPath("Foo"); Assert.NotNull(child.FullPath); }
/// <summary> /// walk the path given in <paramref name="parts" />, from <paramref name="root" /> and return the next possible values /// </summary> /// <param name="root"></param> /// <param name="parts"></param> /// <param name="range"></param> /// <returns></returns> private IResult <IList <DtoConfigKeyCompletion> > GetKeyAutoCompleteInternal(ConfigEnvironmentKeyPath root, ICollection <string> parts, QueryRange range) { _logger.LogDebug($"walking path from '{root.FullPath}' using ({string.Join(",", parts)}), range={range}"); var current = root; var result = new List <ConfigEnvironmentKeyPath>(); var queue = new Queue <string>(parts); // try walking the given path to the deepest part, and return all options the user can take from here while (queue.TryDequeue(out var part)) { _logger.LogTrace($"try walking down '{part}'"); if (string.IsNullOrWhiteSpace(part)) { _logger.LogDebug($"next part is empty, returning '{current.Children.Count}' children"); result = current.Children; break; } var match = current.Children.FirstOrDefault(c => c.Path.Equals(part, StringComparison.OrdinalIgnoreCase)); if (!(match is null)) { _logger.LogDebug($"match for '{part}' found, continuing at '{match.FullPath}' with '{match.Children.Count}' children"); current = match; result = match.Children; continue; } _logger.LogDebug($"no matches found, suggesting "); var suggested = current.Children .Where(c => c.Path.Contains(part, StringComparison.OrdinalIgnoreCase)) .ToList(); if (suggested.Any()) { result = suggested; break; } // take the current ConfigEnvironmentPath object and walk its parents back to the root // to gather info for a more descriptive error-message var walkedPath = new List <string>(); var x = current; walkedPath.Add($"{{END; '{part}'}}"); while (!(x is null)) { walkedPath.Add(x.Path); x = x.Parent; } walkedPath.Add("{START}"); walkedPath.Reverse(); var walkedPathStr = string.Join(" => ", walkedPath); var logMsg = $"no matching objects for '{part}' found; " + $"path taken to get to this dead-end: {walkedPathStr}"; _logger.LogDebug(logMsg); return(Result.Error <IList <DtoConfigKeyCompletion> >(logMsg, ErrorCode.NotFound)); } return(Result.Success <IList <DtoConfigKeyCompletion> >( result.Select(p => new DtoConfigKeyCompletion { FullPath = p.FullPath, HasChildren = p.Children.Any(), Completion = p.Path }) .OrderBy(p => p.Completion) .Skip(range.Offset) .Take(range.Length) .ToList())); }