Skip to content
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,163 @@
using Newtonsoft.Json.Linq;
using System.Text.Json.Serialization;
using APIView.Model.V2;
using Microsoft.CodeAnalysis;
using NuGet.ContentModel;


namespace CSharpAPIParserTests
{
public class CodeFileTests
{
private readonly CodeFile codeFile;
public Assembly assembly { get; set; }
private readonly CodeFile templateCodeFile;
private Assembly templateAssembly { get; set; }
private readonly CodeFile storageCodeFile;
public Assembly storageAssembly { get; set; }
private readonly CodeFile coreCodeFile;
public Assembly coreAssembly { get; set; }

public CodeFileTests()
{
assembly = Assembly.Load("Azure.Template");
var dllStream = assembly.GetFile("Azure.Template.dll");
templateAssembly = Assembly.Load("Azure.Template");
var dllStream = templateAssembly.GetFile("Azure.Template.dll");
var assemblySymbol = CompilationFactory.GetCompilation(dllStream, null);
this.codeFile = new CSharpAPIParser.TreeToken.CodeFileBuilder().Build(assemblySymbol, true, null);
this.templateCodeFile = new CSharpAPIParser.TreeToken.CodeFileBuilder().Build(assemblySymbol, true, null);

this.storageAssembly = Assembly.Load("Azure.Storage.Blobs");
dllStream = storageAssembly.GetFile("Azure.Storage.Blobs.dll");
assemblySymbol = CompilationFactory.GetCompilation(dllStream, null);
this.storageCodeFile = new CSharpAPIParser.TreeToken.CodeFileBuilder().Build(assemblySymbol, true, null);

this.coreAssembly = Assembly.Load("Azure.Core");
dllStream = coreAssembly.GetFile("Azure.Core.dll");
assemblySymbol = CompilationFactory.GetCompilation(dllStream, null);
this.coreCodeFile = new CSharpAPIParser.TreeToken.CodeFileBuilder().Build(assemblySymbol, true, null);
}

[Fact]
public void TestPackageName()
{
Assert.Equal("Azure.Template", codeFile.PackageName);
Assert.Equal("Azure.Template", templateCodeFile.PackageName);
Comment thread
praveenkuttappan marked this conversation as resolved.
Outdated
}

[Fact]
public void TestPackageVersion()
{
Assert.Equal("12.21.2.0", storageCodeFile.PackageVersion);
}

[Fact]
public void TestLanguage()
{
Assert.Equal("C#", storageCodeFile.Language);
}

[Fact]
public void TestTopLevelReviewLineCount()
{
Assert.Equal(8, codeFile.ReviewLines.Count());
Assert.Equal(8, templateCodeFile.ReviewLines.Count());
Comment thread
praveenkuttappan marked this conversation as resolved.
Outdated
}

[Fact]
public void TestClassReviewLineWithoutBase()
{
var lines = storageCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure.Storage.Blobs").FirstOrDefault();
Assert.NotNull(namespaceLine);
var classLine = namespaceLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.BlobServiceClient").FirstOrDefault();
Assert.NotNull(classLine);
Assert.Equal(4, classLine.Tokens.Count());
Assert.Equal("public class BlobServiceClient {", classLine.ToString().Trim());
}

[Fact]
public void TestClassReviewLineWithBase()
{
var lines = storageCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure.Storage.Blobs.Models").FirstOrDefault();
Assert.NotNull(namespaceLine);
var classLine = namespaceLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.Models.BlobDownloadInfo").FirstOrDefault();
Assert.NotNull(classLine);
Assert.Equal(6, classLine.Tokens.Count());
Assert.Equal("public class BlobDownloadInfo : IDisposable {", classLine.ToString().Trim());
}

[Fact]
public void TestMultipleKeywords()
{
var lines = storageCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure.Storage.Blobs.Models").FirstOrDefault();
Assert.NotNull(namespaceLine);
var classLine = namespaceLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.Models.AccessTier").FirstOrDefault();
Assert.NotNull(classLine);
Assert.Equal(10, classLine.Tokens.Count());
Assert.Equal("public readonly struct AccessTier : IEquatable<AccessTier> {", classLine.ToString().Trim());
}

[Fact]
public void TestApiReviewLine()
{
var lines = storageCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure.Storage.Blobs").FirstOrDefault();
Assert.NotNull(namespaceLine);
var classLine = namespaceLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.BlobServiceClient").FirstOrDefault();
Assert.NotNull(classLine);
var methodLine = classLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.BlobServiceClient.BlobServiceClient(System.String)").FirstOrDefault();
Assert.Equal(7, methodLine.Tokens.Count());
Assert.Equal("public BlobServiceClient(string connectionString);", methodLine.ToString().Trim());
}

[Fact]
public void TestApiReviewLineMoreParams()
{
var lines = storageCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure.Storage.Blobs").FirstOrDefault();
Assert.NotNull(namespaceLine);
var classLine = namespaceLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.BlobServiceClient").FirstOrDefault();
Assert.NotNull(classLine);
var methodLine = classLine.Children.Where(lines => lines.LineId.Contains("UndeleteBlobContainerAsync")).FirstOrDefault();
Assert.NotNull(methodLine);
Assert.Equal(23, methodLine.Tokens.Count);
Assert.Equal("public virtual Task<Response<BlobContainerClient>> UndeleteBlobContainerAsync(string deletedContainerName, string deletedContainerVersion, CancellationToken cancellationToken = default);", methodLine.ToString().Trim());
}

[Fact]
public void TestAllClassesHaveEndOfContextLine()
{
// If current line is for class then next line at same level is expected to be a end of context line
var lines = coreCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure").FirstOrDefault();
Assert.NotNull(namespaceLine);
bool expectEndOfContext = false;
var classLines = namespaceLine.Children;
for (int i = 0; i < classLines.Count; i++)
{
if (expectEndOfContext)
{
Assert.True(classLines[i].IsContextEndLine == true);
expectEndOfContext = false;
continue;
}

expectEndOfContext = classLines[i].Tokens.Any(t=> (t.RenderClasses.Contains("class") ||
t.RenderClasses.Contains("struct") ||
t.RenderClasses.Contains("interface")) && !classLines[i].Tokens.Any( t=>t.Value == "abstract"));
}
}

[Fact]
public void TestHiddenAPI()
{
var apiText = "protected static BlobServiceClient CreateClient(Uri serviceUri, BlobClientOptions options, HttpPipelinePolicy authentication, HttpPipeline pipeline);";
var lines = storageCodeFile.ReviewLines;
var namespaceLine = lines.Where(lines => lines.LineId == "Azure.Storage.Blobs").FirstOrDefault();
Assert.NotNull(namespaceLine);
var classLine = namespaceLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.BlobServiceClient").FirstOrDefault();
Assert.NotNull(classLine);
var hiddenApis = classLine.Children.Where(lines => lines.LineId == "Azure.Storage.Blobs.BlobServiceClient.CreateClient(System.Uri, Azure.Storage.Blobs.BlobClientOptions, Azure.Core.Pipeline.HttpPipelinePolicy, Azure.Core.Pipeline.HttpPipeline)").FirstOrDefault();
Assert.NotNull(hiddenApis);
Assert.Equal(18, hiddenApis.Tokens.Count());
Assert.Equal(apiText, hiddenApis.ToString().Trim());
}

[Fact]
Expand Down Expand Up @@ -77,14 +207,14 @@ public static class TemplateClientBuilderExtensions {
}
}
";
Assert.Equal(expected, codeFile.GetApiText());
Assert.Equal(expected, templateCodeFile.GetApiText());
}

[Fact]
public void TestCodeFileJsonSchema()
{
//Verify JSON file generated for Azure.Template
var isValid = validateSchema(codeFile);
var isValid = validateSchema(templateCodeFile);
Assert.True(isValid);
}

Expand Down Expand Up @@ -129,9 +259,9 @@ private bool validateSchema(CodeFile codeFile)
}

[Fact]
public void TestNavigatonNodeHasRenderingClass()
public void TestNavigationNodeHasRenderingClass()
{
var jsonString = JsonSerializer.Serialize(codeFile);
var jsonString = JsonSerializer.Serialize(templateCodeFile);
var parsedCodeFile = JsonSerializer.Deserialize<CodeFile>(jsonString);
Assert.Equal(8, CountNavigationNodes(parsedCodeFile.ReviewLines));
}
Expand Down