Skip to content

Commit

Permalink
- Add more tests
Browse files Browse the repository at this point in the history
- Fix issue with generics and whitespace
  • Loading branch information
eNeRGy164 committed Jan 2, 2020
1 parent e5943de commit 96a927d
Show file tree
Hide file tree
Showing 13 changed files with 492 additions and 65 deletions.
11 changes: 9 additions & 2 deletions LivingDocumentation.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.779
# Visual Studio Version 16
VisualStudioVersion = 16.0.29318.209
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LivingDocumentation.Analyzer", "src\LivingDocumentation.Analyzer\LivingDocumentation.Analyzer.csproj", "{72E336A0-A9D8-494D-9332-CDE8341B247B}"
EndProject
Expand Down Expand Up @@ -35,6 +35,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
GitVersion.yml = GitVersion.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LivingDocumentation.RenderExtensions.Tests", "tests\LivingDocumentation.RenderExtensions.Tests\LivingDocumentation.RenderExtensions.Tests.csproj", "{0A28D3CE-00A8-4473-B571-F8AE0FFFF1AC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -81,6 +83,10 @@ Global
{90E0C6A2-BF79-406D-BC5C-2637AD2BADE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90E0C6A2-BF79-406D-BC5C-2637AD2BADE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90E0C6A2-BF79-406D-BC5C-2637AD2BADE2}.Release|Any CPU.Build.0 = Release|Any CPU
{0A28D3CE-00A8-4473-B571-F8AE0FFFF1AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0A28D3CE-00A8-4473-B571-F8AE0FFFF1AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0A28D3CE-00A8-4473-B571-F8AE0FFFF1AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0A28D3CE-00A8-4473-B571-F8AE0FFFF1AC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -96,6 +102,7 @@ Global
{43F54404-225C-4234-AFA9-A316A891884C} = {2CCF1B57-05F0-4DF7-8B48-29D03CE052F5}
{4CC5B483-9205-47A4-82F8-189047316512} = {2CCF1B57-05F0-4DF7-8B48-29D03CE052F5}
{90E0C6A2-BF79-406D-BC5C-2637AD2BADE2} = {93C52A66-6790-47D3-90A7-26EFFC41D4C6}
{0A28D3CE-00A8-4473-B571-F8AE0FFFF1AC} = {93C52A66-6790-47D3-90A7-26EFFC41D4C6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {298BF1F6-9407-40A1-91C0-F11BA01BD95B}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)
return;
}

if (this.semanticModel.GetConstantValue(node).HasValue && string.Equals((node.Expression as IdentifierNameSyntax)?.Identifier.ValueText, "nameof"))
if (this.semanticModel.GetConstantValue(node).HasValue && string.Equals((node.Expression as IdentifierNameSyntax)?.Identifier.ValueText, "nameof", StringComparison.Ordinal))
{
// nameof is compiler sugar, and is actually a method we are not interrested in
return;
Expand All @@ -96,8 +96,11 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)
methodName = i.Identifier.ValueText;
break;
}
if (methodName == "Fire")
{

var invocation = new InvocationDescription(containingType, methodName);
}
var invocation = new InvocationDescription(containingType, methodName);
this.statements.Add(invocation);

foreach (var argument in node.ArgumentList.Arguments)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
<ItemGroup>
<PackageReference Include="Buildalyzer.Workspaces" Version="2.3.0" />
<PackageReference Include="CommandLineParser" Version="2.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>

Expand Down
40 changes: 40 additions & 0 deletions src/LivingDocumentation.Analyzer/Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using CommandLine;

namespace LivingDocumentation
{
public partial class Program
{
public class Options
{
[Option("solution", Required = true, HelpText = "The solution to analyze.")]
public string SolutionPath
{
get; set;
}

[Option("output", Required = true, HelpText = "The location of the output.")]
public string OutputPath
{
get; set;
}

[Option('v', "verbose", Default = false, HelpText = "Show warnings during compilation.")]
public bool VerboseOutput
{
get; set;
}

[Option('p', "pretty", Default = false, HelpText = "Store JSON output in indented formatting.")]
public bool PrettyPrint
{
get; set;
}

[Option('q', "quiet", Default = false, HelpText = "Don't output informational messages.")]
public bool Quiet
{
get; set;
}
}
}
}
33 changes: 7 additions & 26 deletions src/LivingDocumentation.Analyzer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,20 @@

namespace LivingDocumentation
{
public class Program
public static partial class Program
{
private static ParserResult<Options> ParsedResults;

public static Options RuntimeOptions { get; private set; } = new Options();

public class Options
{
[Option("solution", Required = true, HelpText = "The solution to analyze.")]
public string SolutionPath { get; set; }

[Option("output", Required = true, HelpText = "The location of the output.")]
public string OutputPath { get; set; }

[Option('v', "verbose", Default = false, HelpText = "Show warnings during compilation.")]
public bool VerboseOutput { get; set; }

[Option('p', "pretty", Default = false, HelpText = "Store JSON output in indented formatting.")]
public bool PrettyPrint { get; set;
}

[Option('q', "quiet", Default = false, HelpText = "Don't output informational messages.")]
public bool Quiet { get; set; }
}

public static async Task Main(string[] args)
{
ParsedResults = Parser.Default.ParseArguments<Options>(args);

await ParsedResults.MapResult(
options => RunApplicationAsync(options),
errors => Task.FromResult(1)
);
).ConfigureAwait(false);
}

private static async Task RunApplicationAsync(Options options)
Expand All @@ -54,7 +35,7 @@ private static async Task RunApplicationAsync(Options options)
var types = new List<TypeDescription>();

var stopwatch = Stopwatch.StartNew();
await AnalyzeSolutionAsync(types, options.SolutionPath);
await AnalyzeSolutionAsync(types, options.SolutionPath).ConfigureAwait(false);
stopwatch.Stop();

// Write analysis
Expand All @@ -69,11 +50,11 @@ private static async Task RunApplicationAsync(Options options)

var result = JsonConvert.SerializeObject(types.OrderBy(t => t.FullName), serializerSettings);

await File.WriteAllTextAsync(options.OutputPath, result);
await File.WriteAllTextAsync(options.OutputPath, result).ConfigureAwait(false);

if (!options.Quiet)
{
Console.WriteLine($"Living Documentation Analysis output generated in {stopwatch.ElapsedMilliseconds}ms at {options.OutputPath}");
Console.WriteLine($"Living Documentation Analysis output generated in {stopwatch.ElapsedMilliseconds}ms at {options.OutputPath}");
}
}

Expand All @@ -85,11 +66,11 @@ private static async Task AnalyzeSolutionAsync(IList<TypeDescription> types, str

// Every project in the solution, except unit test projects
var projects = workspace.CurrentSolution.Projects
.Where(p => !manager.Projects.First(mp => p.Id.Id == mp.Value.ProjectGuid).Value.ProjectFile.PackageReferences.Any(pr => pr.Name.Contains("Test")));
.Where(p => !manager.Projects.First(mp => p.Id.Id == mp.Value.ProjectGuid).Value.ProjectFile.PackageReferences.Any(pr => pr.Name.Contains("Test", StringComparison.Ordinal)));

foreach (var project in projects)
{
var compilation = await project.GetCompilationAsync();
var compilation = await project.GetCompilationAsync().ConfigureAwait(false);

if (RuntimeOptions.VerboseOutput)
{
Expand Down
52 changes: 24 additions & 28 deletions src/LivingDocumentation.Render/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,20 @@ public static class StringExtensions
{
public static bool IsEnumerable(this string type)
{
if (type.StartsWith("System.Collections.Generic.", StringComparison.Ordinal))
if (!type.StartsWith("System.Collections.", StringComparison.Ordinal))
{
return false;
}
else if (type.StartsWith("System.Collections.Generic.", StringComparison.Ordinal))
{
return !type.Contains("Enumerator") && !type.Contains("Compar") && !type.Contains("Exception");
}
else if (type.StartsWith("System.Collections.Concurrent.", StringComparison.Ordinal))
{
return !type.Contains("Partition");
}
else if (type.StartsWith("System.Collections.", StringComparison.Ordinal))
{
return !type.Contains("Enumerator") && !type.Contains("Compar") && !type.Contains("Structural") && !type.Contains("Provider");
}
else
{
return false;
}

return !type.Contains("Enumerator") && !type.Contains("Compar") && !type.Contains("Structural") && !type.Contains("Provider");
}

public static bool IsGeneric(this string type)
Expand All @@ -34,29 +32,27 @@ public static bool IsGeneric(this string type)

public static IReadOnlyList<string> GenericTypes(this string type)
{
if (type.IsGeneric())
if (!type.IsGeneric())
{
var typeParts = type.Substring(type.IndexOf('<') + 1, type.Length - type.IndexOf('<') - 2).Split(',');
var types = new List<string>();
return new List<string>(0);
}

foreach (var part in typeParts)
{
if (part.IndexOf('>') > -1 && types.Count > 0 && types.Last().ToCharArray().Count(c => c == '<') > types.Last().ToCharArray().Count(c => c == '>'))
{
types[types.Count - 1] = types[types.Count - 1] + "," + part;
}
else
{
types.Add(part);
}
}
var typeParts = type.Substring(type.IndexOf('<') + 1, type.Length - type.IndexOf('<') - 2).Split(',');
var types = new List<string>();

return types;
}
else
foreach (var part in typeParts)
{
return new List<string>(0);
if (part.IndexOf('>') > -1 && types.Count > 0 && types.Last().ToCharArray().Count(c => c == '<') > types.Last().ToCharArray().Count(c => c == '>'))
{
types[types.Count - 1] = types[types.Count - 1] + "," + part.Trim();
}
else
{
types.Add(part.Trim());
}
}

return types;
}

public static string ForDiagram(this string type)
Expand Down Expand Up @@ -101,4 +97,4 @@ public static string ToSentenceCase(this string input)
return stringBuilder.ToString();
}
}
}
}
20 changes: 20 additions & 0 deletions tests/LivingDocumentation.Analyzer.Tests/EventDeclarationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ class Test
types[0].Events.Should().HaveCount(1);
}

[TestMethod]
public void EventDeclaration_Should_CreateEventDescriptionTests2()
{
// Assign
var source = @"
class Test
{
event System.Action @event;
Test() { @event(); }
}
";

// Act
var types = TestHelper.VisitSyntaxTree(source);

// Assert
types[0].Events.Should().HaveCount(1);
}

[TestMethod]
public void MultipleEventDeclaration_Should_CreateEventDescriptionPerEvent()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.9.0" />
<PackageReference Include="FluentAssertions" Version="5.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.1" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\LivingDocumentation.Render\LivingDocumentation.RenderExtensions.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 96a927d

Please sign in to comment.