Skip to content

Commit

Permalink
Merge pull request #8 from VeyronSakai/refactor-tests
Browse files Browse the repository at this point in the history
Add tests
  • Loading branch information
VeyronSakai authored Apr 7, 2024
2 parents ce38420 + d2e93f8 commit 98bf1bb
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@
namespace VContainerAnalyzer.Test;

[TestFixture]
public class VContainerAnalyzerTest
public class PreserveAttributeAnalyzerTest
{
private const string VContainerDirectory = "VContainer";

private static IEnumerable<string> VContainerSourcePaths { get; } =
GetVContainerFiles.Select(file => $"{Path.Combine(VContainerDirectory, file)}");
GetVContainerFiles.Select(file => $"{Path.Combine(VContainerDirectory, file)}").ToArray();

private static IEnumerable<string> GetVContainerFiles =>
[
"Container.cs",
"ContainerBuilder.cs",
"ContainerBuilderExtensions.cs",
"ContainerBuilderUnityExtensions.cs",
"RegistrationBuilder.cs"
"RegistrationBuilder.cs",
"InjectAttribute.cs",
];

private static string[] ReadCodes(params string[] sources)
Expand All @@ -45,7 +46,7 @@ private static string[] ReadCodes(params string[] sources)
public async Task EmptySourceCode_NoDiagnosticReport()
{
const string Source = "";
var analyzer = new VContainerAnalyzer();
var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, Source);

Assert.That(diagnostics, Is.Empty);
Expand All @@ -55,10 +56,11 @@ public async Task EmptySourceCode_NoDiagnosticReport()
public async ValueTask AnalyzeRegisterEntryPointMethod_ConstructorDoesNotHaveInjectAttribute_ReportDiagnostics()
{
var source = ReadCodes("ConstructorWithoutInjectAttributeClass.cs",
"EmptyClassStub.cs",
"Interfaces.cs",
"RegisterEntryPointConstructorWithoutInjectAttributeClassLifetimeScope.cs");

var analyzer = new VContainerAnalyzer();
var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
Expand All @@ -71,7 +73,7 @@ public async ValueTask AnalyzeRegisterEntryPointMethod_ConstructorDoesNotHaveInj
Assert.That(actual.First().Id, Is.EqualTo("VContainer0001"));
Assert.That(actual.First().GetMessage(),
Is.EqualTo(
"The constructor of 'ConstructorWithoutInjectAttributeClass' does not have InjectAttribute."));
"The constructor of 'ConstructorWithoutInjectAttributeClass' have no attribute that extends PreserveAttribute, such as InjectAttribute."));
});

var expectedPositions = new[]
Expand Down Expand Up @@ -99,7 +101,7 @@ public async ValueTask AnalyzeRegisterEntryPointMethod_ConstructorDoesNotExist_R
"Interfaces.cs",
"RegisterEntryPointNoConstructorClassLifetimeScope.cs");

var analyzer = new VContainerAnalyzer();
var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
Expand All @@ -114,10 +116,11 @@ public async ValueTask AnalyzeRegisterEntryPointMethod_ConstructorDoesNotExist_R
public async ValueTask AnalyzeRegisterMethod_ConstructorDoesNotHaveInjectAttribute_ReportDiagnostics()
{
var source = ReadCodes("ConstructorWithoutInjectAttributeClass.cs",
"EmptyClassStub.cs",
"Interfaces.cs",
"RegisterConstructorWithoutInjectAttributeClassLifetimeScope.cs");

var analyzer = new VContainerAnalyzer();
var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
Expand All @@ -130,7 +133,7 @@ public async ValueTask AnalyzeRegisterMethod_ConstructorDoesNotHaveInjectAttribu
Assert.That(actual.First().Id, Is.EqualTo("VContainer0001"));
Assert.That(actual.First().GetMessage(),
Is.EqualTo(
"The constructor of 'ConstructorWithoutInjectAttributeClass' does not have InjectAttribute."));
"The constructor of 'ConstructorWithoutInjectAttributeClass' have no attribute that extends PreserveAttribute, such as InjectAttribute."));
});

var expectedPositions = new[]
Expand Down Expand Up @@ -161,7 +164,63 @@ public async ValueTask AnalyzeRegisterMethod_ConstructorDoesNotExist_ReportNoDia
"Interfaces.cs",
"RegisterNoConstructorClassLifetimeScope.cs");

var analyzer = new VContainerAnalyzer();
var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
.Where(x => x.Id != "CS1591") // Ignore "Missing XML comment for publicly visible type or member"
.Where(x => x.Id != "CS8019") // Ignore "Unnecessary using directive"
.ToArray();

Assert.That(actual.Length, Is.EqualTo(0));
}

[Test]
public async ValueTask AnalyzeRegisterMethod_OnlyDefaultConstructorExists_ReportNoDiagnostics()
{
var source = ReadCodes("DefaultConstructorClass.cs",
"Interfaces.cs",
"RegisterDefaultConstructorClassLifetimeScope.cs");

var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
.Where(x => x.Id != "CS1591") // Ignore "Missing XML comment for publicly visible type or member"
.Where(x => x.Id != "CS8019") // Ignore "Unnecessary using directive"
.ToArray();

Assert.That(actual.Length, Is.EqualTo(0));
}

[Test]
public async ValueTask AnalyzeRegisterEntryPointMethod_ConstructorHasInjectAttribute_ReportNoDiagnostics()
{
var source = ReadCodes("ConstructorWithInjectAttributeClass.cs",
"EmptyClassStub.cs",
"Interfaces.cs",
"RegisterEntryPointConstructorWithInjectAttributeClassLifetimeScope.cs");

var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
.Where(x => x.Id != "CS1591") // Ignore "Missing XML comment for publicly visible type or member"
.Where(x => x.Id != "CS8019") // Ignore "Unnecessary using directive"
.ToArray();

Assert.That(actual.Length, Is.EqualTo(0));
}

[Test]
public async ValueTask AnalyzeRegisterMethod_ConstructorHasInjectAttribute_ReportNoDiagnostics()
{
var source = ReadCodes("ConstructorWithInjectAttributeClass.cs",
"EmptyClassStub.cs",
"Interfaces.cs",
"RegisterConstructorWithInjectAttributeClassLifetimeScope.cs");

var analyzer = new PreserveAttributeAnalyzer();
var diagnostics = await DiagnosticAnalyzerRunner.Run(analyzer, source);

var actual = diagnostics
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2020-2024 VeyronSakai.
// This software is released under the MIT License.

using System;
using VContainer;

namespace VContainerAnalyzer.Test.TestData
{
public class ConstructorWithInjectAttributeClass : IInterface1, IInterface2, IInterface3
{
[Inject]
public ConstructorWithInjectAttributeClass(EmptyClassStub stub1, EmptyClassStub stub2)
{
Console.WriteLine("");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace VContainerAnalyzer.Test.TestData
{
public class ConstructorWithoutInjectAttributeClass : IInterface1, IInterface2, IInterface3
{
public ConstructorWithoutInjectAttributeClass(int x, int y)
public ConstructorWithoutInjectAttributeClass(EmptyClassStub stub1, EmptyClassStub stub2)
{
Console.WriteLine("");
}
Expand Down
9 changes: 9 additions & 0 deletions VContainerAnalyzer.Test/TestData/EmptyClassStub.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) 2020-2024 VeyronSakai.
// This software is released under the MIT License.

namespace VContainerAnalyzer.Test.TestData
{
public class EmptyClassStub
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2020-2024 VeyronSakai.
// This software is released under the MIT License.

using VContainer;

namespace VContainerAnalyzer.Test.TestData
{
public class RegisterConstructorWithInjectAttributeClassLifetimeScope
{
// ReSharper disable once UnusedMember.Global
public void Configure(IContainerBuilder builder)
{
builder.Register<ConstructorWithInjectAttributeClass>(Lifetime.Singleton);
builder.Register<ConstructorWithInjectAttributeClass>(Lifetime.Singleton).As<IInterface1>();
builder.Register<IInterface1, ConstructorWithInjectAttributeClass>(Lifetime.Singleton);
builder.Register<IInterface1, IInterface2, ConstructorWithInjectAttributeClass>(Lifetime.Singleton);
builder.Register<IInterface1, IInterface2, IInterface3, ConstructorWithInjectAttributeClass>(
Lifetime.Singleton);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2020-2024 VeyronSakai.
// This software is released under the MIT License.

using VContainer;

namespace VContainerAnalyzer.Test.TestData
{
public class RegisterDefaultConstructorClassLifetimeScope
{
public void Configure(IContainerBuilder builder)
{
builder.Register<DefaultConstructorClass>(Lifetime.Singleton);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2020-2024 VeyronSakai.
// This software is released under the MIT License.

using VContainer;
using VContainer.Unity;

namespace VContainerAnalyzer.Test.TestData
{
public class RegisterEntryPointConstructorWithInjectAttributeClassLifetimeScope
{
// ReSharper disable once UnusedMember.Global
public void Configure(IContainerBuilder builder)
{
builder.RegisterEntryPoint<ConstructorWithInjectAttributeClass>();
builder.RegisterEntryPoint<ConstructorWithInjectAttributeClass>(Lifetime.Singleton);
}
}
}
25 changes: 25 additions & 0 deletions VContainerAnalyzer.Test/TestData/VContainer/InjectAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2020-2024 VeyronSakai.
// This software is released under the MIT License.

using System;

// ReSharper disable once CheckNamespace
namespace VContainer
{
public class PreserveAttribute : Attribute
{
}

[AttributeUsage(
AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field,
AllowMultiple = false, Inherited = true)]
public class InjectAttribute : PreserveAttribute
{
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface,
AllowMultiple = false, Inherited = true)]
public class InjectIgnoreAttribute : Attribute
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@
namespace VContainerAnalyzer;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class VContainerAnalyzer : DiagnosticAnalyzer
public sealed class PreserveAttributeAnalyzer : DiagnosticAnalyzer
{
private const string DiagnosticId = "VContainer0001";

private static readonly DiagnosticDescriptor s_rule = new(
id: DiagnosticId,
title: "Constructor does not have InjectAttribute.",
messageFormat: "The constructor of '{0}' does not have InjectAttribute.",
title: "Constructor have no attribute that extends PreserveAttribute, such as InjectAttribute.",
messageFormat:
"The constructor of '{0}' have no attribute that extends PreserveAttribute, such as InjectAttribute.",
category: "Usage",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: "Constructor must have InjectAttribute.");
description: "Constructor must have attribute that extends PreserveAttribute, such as InjectAttribute.");

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(s_rule);

Expand Down
3 changes: 3 additions & 0 deletions VContainerAnalyzer/VContainerAnalyzer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<ItemGroup Condition="Exists('$(TargetPath)')">
<Analyzer Include="$(TargetPath)"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Analyzers\" />
</ItemGroup>

<!-- For pack -->
<PropertyGroup>
Expand Down

0 comments on commit 98bf1bb

Please sign in to comment.