Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
28 changes: 1 addition & 27 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,6 @@ jobs:
./Artifacts/*
./TestResults/*.trx

api-tests:
name: "API tests"
runs-on: ubuntu-latest
env:
DOTNET_NOLOGO: true
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup .NET SDKs
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x
- name: API checks
run: ./build.sh ApiChecks
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: API-tests
path: |
./Artifacts/*
./TestResults/*.trx

benchmarks:
name: "Benchmarks"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -105,7 +79,7 @@ jobs:

publish-test-results:
name: "Publish Tests Results"
needs: [ api-tests, unit-tests ]
needs: [ unit-tests ]
runs-on: ubuntu-latest
permissions:
checks: write
Expand Down
28 changes: 1 addition & 27 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,6 @@ jobs:
./Artifacts/*
./TestResults/*.trx

api-tests:
name: "API tests"
runs-on: ubuntu-latest
env:
DOTNET_NOLOGO: true
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup .NET SDKs
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x
- name: API checks
run: ./build.sh ApiChecks
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: API-tests
path: |
./Artifacts/*
./TestResults/*.trx

benchmarks:
name: "Benchmarks"
runs-on: ubuntu-latest
Expand Down Expand Up @@ -111,7 +85,7 @@ jobs:

publish-test-results:
name: "Publish Tests Results"
needs: [ api-tests, unit-tests ]
needs: [ unit-tests ]
runs-on: ubuntu-latest
permissions:
Comment thread
vbreuss marked this conversation as resolved.
checks: write
Expand Down
15 changes: 14 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
<PackageVersion Include="LibGit2Sharp" Version="0.31.0"/>
<PackageVersion Include="SharpCompress" Version="0.47.3"/>
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.CodeAnalysis" Version="4.11.0"/>
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeRefactoring.Testing" Version="1.1.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.11.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.11.0" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.163"/>
</ItemGroup>
Expand All @@ -23,8 +34,10 @@
<PackageVersion Include="xunit.v3" Version="3.2.2"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5"/>
<PackageVersion Include="coverlet.collector" Version="8.0.1"/>
<PackageVersion Include="PublicApiGenerator" Version="11.5.4"/>
<PackageVersion Include="aweXpect" Version="2.31.0"/>
<PackageVersion Include="aweXpect.Chronology" Version="1.0.0"/>
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Moq" Version="4.20.72"/>
</ItemGroup>
</Project>
4 changes: 3 additions & 1 deletion Mockolate.Migration.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Project Path="Pipeline/Build.csproj" />
</Folder>
<Folder Name="/Tests/">
<Project Path="Tests/Mockolate.Migration.Api.Tests/Mockolate.Migration.Api.Tests.csproj" />
<Project Path="Tests/Mockolate.Migration.Example.Tests/Mockolate.Migration.Example.Tests.csproj" />
<Project Path="Tests/Mockolate.Migration.Tests/Mockolate.Migration.Tests.csproj" />
</Folder>
<Folder Name="/_/">
Expand Down Expand Up @@ -35,5 +35,7 @@
<Folder Name="/_/Tests/">
<File Path="Tests/Directory.Build.props" />
</Folder>
<Project Path="Source/Mockolate.Migration.Analyzers.CodeFixers/Mockolate.Migration.Analyzers.CodeFixers.csproj" />
<Project Path="Source/Mockolate.Migration.Analyzers/Mockolate.Migration.Analyzers.csproj" />
<Project Path="Source/Mockolate.Migration/Mockolate.Migration.csproj" />
</Solution>
28 changes: 0 additions & 28 deletions Pipeline/Build.ApiChecks.cs

This file was deleted.

2 changes: 1 addition & 1 deletion Pipeline/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ partial class Build : NukeBuild
AbsolutePath TestResultsDirectory => RootDirectory / "TestResults";
GitHubActions GitHubActions => GitHubActions.Instance;

public static int Main() => Execute<Build>(x => x.ApiChecks, x => x.Benchmarks, x => x.CodeAnalysis);
public static int Main() => Execute<Build>(x => x.Benchmarks, x => x.CodeAnalysis);
}
8 changes: 4 additions & 4 deletions Source/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
Condition="Exists('$(MSBuildThisFileDirectory)/../Directory.Build.props')"/>

<PropertyGroup>
<Authors>aweXpect</Authors>
<Description>Template for extension projects for aweXpect.</Description>
<Copyright>Copyright (c) 2025 - $([System.DateTime]::Now.ToString('yyyy')) Valentin Breuß</Copyright>
<Authors>Mockolate</Authors>
<Description>Migration helpers from other mocking libraries.</Description>
<Copyright>Copyright (c) 2026 - $([System.DateTime]::Now.ToString('yyyy')) Valentin Breuß</Copyright>
<RepositoryUrl>https://github.com/aweXpect/Mockolate.Migration.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand All @@ -15,7 +15,7 @@
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>net10.0;net8.0;netstandard2.0</TargetFrameworks>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;

namespace Mockolate.Migration.Analyzers;

/// <summary>
/// Base class for code fix provider that migrates assertions to aweXpect.
/// </summary>
public abstract class AssertionCodeFixProvider(DiagnosticDescriptor rule) : CodeFixProvider
{
/// <inheritdoc />
public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } = [rule.Id,];

/// <inheritdoc />
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

/// <inheritdoc />
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
foreach (Diagnostic? diagnostic in context.Diagnostics)
{
TextSpan diagnosticSpan = diagnostic.Location.SourceSpan;

SyntaxNode? root =
await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

if (root?.FindNode(diagnosticSpan) is ExpressionSyntax expressionSyntax
and (InvocationExpressionSyntax or ConditionalAccessExpressionSyntax or LambdaExpressionSyntax))
{
context.RegisterCodeFix(
CodeAction.Create(
rule.Title.ToString(),
c => ConvertAssertionAsync(context, expressionSyntax, c),
rule.Title.ToString()),
diagnostic);
}
}
}

/// <summary>
/// Converts the assertion.
/// </summary>
protected abstract Task<Document> ConvertAssertionAsync(CodeFixContext context,
ExpressionSyntax expressionSyntax, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Code fix providers for Mockolate to migrate from other mocking libraries.</Description>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<IsRoslynComponent>true</IsRoslynComponent>
<DevelopmentDependency>false</DevelopmentDependency>
<NoPackageAnalysis>true</NoPackageAnalysis>
<NoWarn>RS2003</NoWarn>
<EnableTrimAnalyzer>false</EnableTrimAnalyzer>
<IsPackable>false</IsPackable>
</PropertyGroup>

<PropertyGroup>
<RootNamespace>Mockolate.Migration.Analyzers</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Common"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"/>
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Mockolate.Migration.Analyzers\Mockolate.Migration.Analyzers.csproj"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;

#pragma warning disable S1192 // String literals should not be duplicated
namespace Mockolate.Migration.Analyzers;

/// <summary>
/// A code fix provider that migrates Moq to Mockolate.
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(MoqCodeFixProvider))]
[Shared]
public class MoqCodeFixProvider() : AssertionCodeFixProvider(Rules.MoqRule)
{
/// <inheritdoc />
protected override async Task<Document> ConvertAssertionAsync(CodeFixContext context,
ExpressionSyntax expressionSyntax, CancellationToken cancellationToken)
{
Document? document = context.Document;
Comment thread
vbreuss marked this conversation as resolved.

SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

if (root is not CompilationUnitSyntax compilationUnit)

Check warning on line 26 in Source/Mockolate.Migration.Analyzers.CodeFixers/MoqCodeFixProvider.cs

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused local variable 'compilationUnit'.

See more on https://sonarcloud.io/project/issues?id=aweXpect_Mockolate.Migration&issues=AZ1Z4Pqhiq29Pk22qQuO&open=AZ1Z4Pqhiq29Pk22qQuO&pullRequest=11
{
return document;
}

return document;
}
}

#pragma warning restore S1192
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
## Release 1.0

### New Rules

Rule ID | Category | Severity | Notes
--------------|----------|----------|-------------------------------------------
MockolateM001 | Usage | Warning | Moq should be migrated.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### New Rules

Rule ID | Category | Severity | Notes
---------|----------|----------|-------
36 changes: 36 additions & 0 deletions Source/Mockolate.Migration.Analyzers/Common/TypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.CodeAnalysis;

namespace Mockolate.Migration.Analyzers.Common;

internal static class TypeExtensions
{
private static readonly SymbolDisplayFormat FullyQualifiedNonGenericWithGlobalPrefix = new(
SymbolDisplayGlobalNamespaceStyle.Included,
SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
SymbolDisplayGenericsOptions.None,
SymbolDisplayMemberOptions.IncludeContainingType,
SymbolDisplayDelegateStyle.NameAndSignature,
SymbolDisplayExtensionMethodStyle.Default,
SymbolDisplayParameterOptions.IncludeType,
SymbolDisplayPropertyStyle.NameOnly,
SymbolDisplayLocalOptions.IncludeType
);

private static readonly SymbolDisplayFormat? FullyQualifiedGenericWithGlobalPrefix = new(
SymbolDisplayGlobalNamespaceStyle.Included,
SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
SymbolDisplayGenericsOptions.None,
SymbolDisplayMemberOptions.IncludeContainingType,
SymbolDisplayDelegateStyle.NameAndSignature,
SymbolDisplayExtensionMethodStyle.Default,
SymbolDisplayParameterOptions.IncludeType,
SymbolDisplayPropertyStyle.NameOnly,
SymbolDisplayLocalOptions.IncludeType
);

public static string GloballyQualified(this ISymbol typeSymbol) =>
typeSymbol.ToDisplayString(FullyQualifiedGenericWithGlobalPrefix);

public static string GloballyQualifiedNonGeneric(this ISymbol typeSymbol) =>
typeSymbol.ToDisplayString(FullyQualifiedNonGenericWithGlobalPrefix);
}
Loading
Loading