public void GetHelpInfo_WhenFileMissing_Throws() { var reader = new NamingConventionXmlDocumentationFileHelpReader("DoesNotExist.xml"); Assert.Throws <ExecutableHelpFileNotFoundExeption>(() => reader.GetHelpInfo(HelpAdjacencyCriteria.Empty())); }
public void GetHelpInfo_WhenFileContainsNoData_ReturnsEmptyList() { var reader = new NamingConventionXmlDocumentationFileHelpReader("Data\\Executables-Empty.xml"); var results = reader.GetHelpInfo(HelpAdjacencyCriteria.Empty()); results.Should().HaveCount(0); }
public void GetHelpInfo_WhenEmptyAdjacencyCriteria_ReturnsDefaultInfoWithFirstTierCategories() { var reader = new JsonFileCategoryHelpReader("Data\\Categories.json", new HelpInfo("default", "subject", "description", HelpInfoType.Category)); var result = reader.GetHelpInfo(HelpAdjacencyCriteria.Empty()); result.Name.Should().Be("default"); result.Subject.Should().Be("subject"); result.Description.Should().Be("description"); result.Type.Should().Be(HelpInfoType.Category); result.Children.Should().HaveCount(2); var child1 = result.Children.First(h => h.Name == "category1"); child1.Name.Should().Be("category1"); child1.Subject.Should().Be("category1"); child1.Description.Should().Be("category1 description"); child1.Type.Should().Be(HelpInfoType.Category); var child2 = result.Children.First(h => h.Name == "category2"); child2.Name.Should().Be("category2"); child2.Subject.Should().Be("category2"); child2.Description.Should().Be("category2 description"); child2.Type.Should().Be(HelpInfoType.Category); }
public void GetHelpInfo_WhenFileIsNotCorrectlyFormatted_Throws() { var reader = new NamingConventionXmlDocumentationFileHelpReader("Data\\Executables-IncorrectlyFormatted.txt"); Assert.Throws <ExecutableHelpFileInvalidExeption>(() => reader.GetHelpInfo(HelpAdjacencyCriteria.Empty())); }
public HelpInfo GetHelpInfo(HelpAdjacencyCriteria adjacencyCriteria) { Guard.AgainstNullArgument(nameof(adjacencyCriteria), adjacencyCriteria); if (!File.Exists(_filePath)) { throw new CategoryHelpFileNotFoundExeption(); } var data = TryDeserialize(File.ReadAllText(_filePath)); var categories = data .Where(kvp => IsSubjectOrOneLevelDeeper(kvp.Key)) .Select(kvp => new HelpInfo( kvp.Key.IndexOf(' ') > -1 ? kvp.Key.Substring(kvp.Key.IndexOf(' ') + 1) : kvp.Key, kvp.Key.Split(' ').FirstOrDefault(), kvp.Value, HelpInfoType.Category)) .ToList(); if (adjacencyCriteria.Equals(HelpAdjacencyCriteria.Empty())) { return(_defaultHelpInfo.WithChildren(categories)); } if (categories.Any(h => h.Subject == adjacencyCriteria.Subject)) { return(categories .First(h => h.Name == adjacencyCriteria.Subject) .WithChildren(categories.Where(h => h.Name != adjacencyCriteria.Subject))); } return(null); Dictionary <string, string> TryDeserialize(string json) { try { return(JsonConvert.DeserializeObject <Dictionary <string, string> >(json)); } catch { throw new CategoryHelpFileInvalidExeption(); } } bool IsSubjectOrOneLevelDeeper(string key) { var keySplit = key.Split(' '); var adjacencySplit = adjacencyCriteria.Subject .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (adjacencyCriteria.Subject == null && keySplit.Length == 1) { return(true); } return(key.StartsWith(adjacencyCriteria.Subject) && (keySplit.Length == adjacencySplit.Length || keySplit.Length == adjacencySplit.Length + 1)); } }
public void GetHelpInfo_WhenFileContainsNoData_ReturnsDefaultHelpInfo() { var reader = new JsonFileCategoryHelpReader("Data\\Categories-Empty.json", new HelpInfo("default", "subject", "description", HelpInfoType.Category)); var result = reader.GetHelpInfo(HelpAdjacencyCriteria.Empty()); result.Name.Should().Be("default"); result.Subject.Should().Be("subject"); result.Description.Should().Be("description"); result.Type.Should().Be(HelpInfoType.Category); }
public HelpInfo Create(string[] args) { var argsWithoutParams = args .Take(GetFirstParamIndex()) .ToArray(); var categoryBySubjectCriteria = CreateSubjectCriteria(); var categoryBySubject = _categoryHelpReader.GetHelpInfo( categoryBySubjectCriteria); if (categoryBySubject != null) { return(GetCategoryHelpInfoWithChildren()); } var executablesBySubject = _executableHelpReader .GetHelpInfo(categoryBySubjectCriteria) .ToArray(); if (executablesBySubject.Any()) { return(new HelpInfo( categoryBySubjectCriteria.Subject, categoryBySubjectCriteria.Subject, string.Empty, HelpInfoType.Category, executablesBySubject)); } var executableBySubjectAndAction = _executableHelpReader .GetHelpInfo(CreateSubjectAndActionCriteria()) .FirstOrDefault(); return(executableBySubjectAndAction); int GetFirstParamIndex() { return(args .Select((arg, index) => new { Value = arg, Index = index }) .FirstOrDefault(arg => arg.Value.StartsWith("-"))?.Index ?? args.Length); } HelpAdjacencyCriteria CreateSubjectCriteria() { var subject = string.Join(" ", argsWithoutParams); return(!string.IsNullOrWhiteSpace(subject) ? new HelpAdjacencyCriteria(subject) : HelpAdjacencyCriteria.Empty()); } HelpAdjacencyCriteria CreateSubjectAndActionCriteria() { var subject = string.Join(" ", argsWithoutParams.Take(argsWithoutParams.Length - 1)); var action = argsWithoutParams.Last(); return(new HelpAdjacencyCriteria(subject, action)); } HelpInfo GetCategoryHelpInfoWithChildren() { var childExecutables = _executableHelpReader .GetHelpInfo(categoryBySubjectCriteria) .ToList(); return(categoryBySubject.WithChildren( categoryBySubject.Children.Union(childExecutables))); } }
public void GetHelpInfo_WhenFileIsNotCorrectlyFormatted_Throws() { var reader = new JsonFileCategoryHelpReader("Data\\Categories-IncorrectlyFormatted.txt"); Assert.Throws <CategoryHelpFileInvalidExeption>(() => reader.GetHelpInfo(HelpAdjacencyCriteria.Empty())); }
public void GetHelpInfo_WhenFileMissing_Throws() { var reader = new JsonFileCategoryHelpReader("Data\\Categories-DoesNotExist.json"); Assert.Throws <CategoryHelpFileNotFoundExeption>(() => reader.GetHelpInfo(HelpAdjacencyCriteria.Empty())); }
private bool Equals(HelpAdjacencyCriteria other) { return(string.Equals(Subject, other.Subject) && string.Equals(Action, other.Action)); }
private static IEnumerable <HelpInfo> Read(string filePath, HelpAdjacencyCriteria adjacencyCriteria) { Guard.AgainstNullArgument(nameof(adjacencyCriteria), adjacencyCriteria); if (!File.Exists(filePath)) { throw new ExecutableHelpFileNotFoundExeption(); } try { var document = XDocument.Load(filePath); var results = document.Root.Element("members").Elements("member") .Where(IsConstructorWithDocumentation) .Select(CreateHelpInfo) .Where(h => adjacencyCriteria.Subject == h.Subject) .Where(h => string.IsNullOrWhiteSpace(adjacencyCriteria.Action) || adjacencyCriteria.Action == h.Name) .ToArray(); return(results); } catch { throw new ExecutableHelpFileInvalidExeption(); } bool IsConstructorWithDocumentation(XElement element) { return(element.Attribute("name").Value.Contains("#ctor")); } HelpInfo CreateHelpInfo(XElement constructorElement) { var splitTypeName = SplitTypeName(GetTypeName(constructorElement)); var subjectName = string.Join(" ", splitTypeName.Skip(1)); var actionName = splitTypeName.First(); return(new HelpInfo( actionName, subjectName, constructorElement.Element("summary")?.Value.Trim(), HelpInfoType.Executable, constructorElement.Elements("param") .Select(p => new HelpInfo( $"{p.Attribute("name")?.Value}", $"{subjectName} {actionName}", p.Value, HelpInfoType.Parameter)) .ToArray())); } string GetTypeName(XElement constructorElement) { return(constructorElement.Attribute("name").Value .Split(new[] { "#ctor" }, StringSplitOptions.RemoveEmptyEntries) .First().Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries) .Last()); } string[] SplitTypeName(string typeName) { return(Regex.Replace(typeName, "((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", " $1") .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) .Select(s => s.ToLower(CultureInfo.InvariantCulture)) .ToArray()); } }
public IEnumerable <HelpInfo> GetHelpInfo(HelpAdjacencyCriteria adjacencyCriteria) { return(_filePaths .SelectMany(filePath => Read(filePath, adjacencyCriteria)) .ToList()); }