Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ jobs:
path: |
**/*.nupkg
**/*.snupkg

# Test that MSBuild properties to disable generators work correctly
- name: Test Generator Disable Properties
run: |
<# Create a local NuGet source directory with the packed packages #>
New-Item -ItemType Directory -Force -Path ./nupkgs
Copy-Item -Path *.nupkg -Destination ./nupkgs/

<# Build and run the disable tests using the local NuGet package #>
<# The test project's NuGet.config points to ../../nupkgs relative to the project #>
dotnet test --project ./GeneratorTests/Moq.AutoMock.Generator.DisableTests/Moq.AutoMock.Generator.DisableTests.csproj `
--configuration Release `
--verbosity normal `
/p:LocalNuGetSource=true

# Update the docs
- name: Update Docs
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

bin/
obj/
build/
packages/

*.suo
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<PackageVersion Include="Microsoft.CodeAnalysis" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.MSTest" Version="1.1.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Testing" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System.Reflection;
using Xunit;

namespace Moq.AutoMock.Generator.DisableTests;

/// <summary>
/// These tests verify that when the MSBuild properties are set to disable the generators,
/// the generated extension methods are not present.
///
/// Each generator produces a static extension class with specific methods. When disabled,
/// these types should not exist in the current assembly (the test project's compilation).
/// The source generators add code to the consuming project, so we check the current assembly.
/// </summary>
public class GeneratorDisableTests
{
private static readonly Assembly CurrentAssembly = typeof(GeneratorDisableTests).Assembly;

[Fact]
public void OptionsGenerator_WhenDisabled_ExtensionMethodDoesNotExist()
{
// When EnableMoqAutoMockerOptionsGenerator=false, the AutoMockerOptionsExtensions class
// should not be generated in this assembly

bool hasGeneratedOptionsExtension = HasExtensionMethod("WithOptions");
Assert.False(hasGeneratedOptionsExtension,
"WithOptions extension method should not exist when EnableMoqAutoMockerOptionsGenerator=false");
}

[Fact]
public void KeyedServicesGenerator_WhenDisabled_ExtensionMethodDoesNotExist()
{
// When EnableMoqAutoMockerKeyedServicesGenerator=false, the keyed services extension
// methods should not be generated

bool hasGeneratedKeyedExtension = HasExtensionMethod("WithKeyedService");
Assert.False(hasGeneratedKeyedExtension,
"WithKeyedService extension method should not exist when EnableMoqAutoMockerKeyedServicesGenerator=false");
}

[Fact]
public void FakeLoggingGenerator_WhenDisabled_ExtensionMethodDoesNotExist()
{
// When EnableMoqAutoMockerFakeLoggingGenerator=false, the fake logging extension
// methods should not be generated

bool hasGeneratedLoggingExtension = HasExtensionMethod("WithFakeLogging");
Assert.False(hasGeneratedLoggingExtension,
"WithFakeLogging extension method should not exist when EnableMoqAutoMockerFakeLoggingGenerator=false");
}

[Fact]
public void ApplicationInsightsGenerator_WhenDisabled_ExtensionMethodDoesNotExist()
{
// When EnableMoqAutoMockerApplicationInsightsGenerator=false, the Application Insights
// extension methods should not be generated

bool hasGeneratedAppInsightsExtension = HasExtensionMethod("WithApplicationInsights");
Assert.False(hasGeneratedAppInsightsExtension,
"WithApplicationInsights extension method should not exist when EnableMoqAutoMockerApplicationInsightsGenerator=false");
}

/// <summary>
/// Checks if an extension method with the given name exists for the AutoMocker type
/// in the current assembly (generated code is added to the consuming project).
/// </summary>
private static bool HasExtensionMethod(string methodName)
{
// Check all types in the current assembly for extension methods on AutoMocker
foreach (var type in CurrentAssembly.GetTypes())
{
if (!type.IsSealed || !type.IsAbstract) // static classes are sealed and abstract
continue;

if (!type.Namespace?.StartsWith("Moq.AutoMock") ?? true)
continue;

var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
foreach (var method in methods)
{
if (method.Name == methodName)
{
var parameters = method.GetParameters();
if (parameters.Length > 0 && parameters[0].ParameterType == typeof(AutoMocker))
{
return true;
}
}
}
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<EnableXunitRunner>true</EnableXunitRunner>

<!-- Disable all Moq.AutoMocker generators -->
<EnableMoqAutoMockerOptionsGenerator>false</EnableMoqAutoMockerOptionsGenerator>
<EnableMoqAutoMockerKeyedServicesGenerator>false</EnableMoqAutoMockerKeyedServicesGenerator>
<EnableMoqAutoMockerFakeLoggingGenerator>false</EnableMoqAutoMockerFakeLoggingGenerator>
<EnableMoqAutoMockerApplicationInsightsGenerator>false</EnableMoqAutoMockerApplicationInsightsGenerator>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.Extensions.Options" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.ApplicationInsights" />
<PackageReference Include="xunit.v3" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<!--
This project references the Moq.AutoMock NuGet package from a local source.
The CI pipeline will set the LocalNuGetSource property to the directory containing
the packed .nupkg files.
We use VersionOverride to bypass Central Package Management for this package
since we're using a locally-built package.
Using *-* to match any version including prerelease (e.g., 3.6.2-ci0123 in CI)
and stable releases. The NuGet.config package source mapping ensures only the
local source is used for Moq.AutoMock.
-->
<ItemGroup Condition="'$(LocalNuGetSource)' != ''">
<PackageReference Include="Moq.AutoMock" VersionOverride="*-*" />
</ItemGroup>

<!-- For local development, use project reference -->
<ItemGroup Condition="'$(LocalNuGetSource)' == ''">
<ProjectReference Include="..\..\Moq.AutoMock\Moq.AutoMock.csproj" />
<ProjectReference Include="..\..\Moq.AutoMocker.Generators\Moq.AutoMocker.Generators.csproj">
<OutputItemType>Analyzer</OutputItemType>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<!--
When using project references, we need to manually declare CompilerVisibleProperty items
since the .props file from the NuGet package won't be applied.
-->
<CompilerVisibleProperty Include="EnableMoqAutoMockerOptionsGenerator" />
<CompilerVisibleProperty Include="EnableMoqAutoMockerKeyedServicesGenerator" />
<CompilerVisibleProperty Include="EnableMoqAutoMockerFakeLoggingGenerator" />
<CompilerVisibleProperty Include="EnableMoqAutoMockerApplicationInsightsGenerator" />
</ItemGroup>

</Project>
20 changes: 20 additions & 0 deletions GeneratorTests/Moq.AutoMock.Generator.DisableTests/NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--
For testing the generator disable properties, we need to use the locally-built package.
The local source must be the primary source for Moq.AutoMock.
-->
<clear />
<add key="local" value="../../nupkgs" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceMapping>
<packageSource key="local">
<package pattern="Moq.AutoMock" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
</packageSourceMapping>
</configuration>
3 changes: 2 additions & 1 deletion Moq.AutoMock/Moq.AutoMock.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Copyright>Copyright © $([System.DateTime]::UtcNow.ToString("yyyy"))</Copyright>
<NeutralLanguage>en-US</NeutralLanguage>

<VersionPrefix Condition="'$(VersionPrefix)' == ''">3.6.1</VersionPrefix>
<VersionPrefix Condition="'$(VersionPrefix)' == ''">3.6.2</VersionPrefix>

<Authors>Tim Kellogg, Adam Hewitt, Kevin Bost</Authors>
<PackageDescription>An auto-mocking container that generates mocks using Moq</PackageDescription>
Expand Down Expand Up @@ -49,6 +49,7 @@
<None Include="..\LICENSE" Pack="true" PackagePath="" />
<Compile Include="..\System.Diagnostics.CodeAnalysis.cs" />
<None Include="..\Moq.AutoMocker.Generators\bin\$(Configuration)\netstandard2.0\*.dll" Pack="True" PackagePath="analyzers\dotnet\cs" />
<None Include="build\Moq.AutoMock.props" Pack="true" PackagePath="build\" />
</ItemGroup>

<ItemGroup>
Expand Down
12 changes: 12 additions & 0 deletions Moq.AutoMock/build/Moq.AutoMock.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
Make MSBuild properties visible to the Roslyn compiler for source generators.
See: https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.cookbook.md#consume-msbuild-properties-and-metadata
-->
<ItemGroup>
<CompilerVisibleProperty Include="EnableMoqAutoMockerOptionsGenerator" />
<CompilerVisibleProperty Include="EnableMoqAutoMockerKeyedServicesGenerator" />
<CompilerVisibleProperty Include="EnableMoqAutoMockerFakeLoggingGenerator" />
<CompilerVisibleProperty Include="EnableMoqAutoMockerApplicationInsightsGenerator" />
</ItemGroup>
</Project>
Loading