Skip to content
This repository was archived by the owner on Jun 30, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
973fd6d
Initial support for a legacy API shim
kzu Jul 23, 2019
b83445a
Add codegen support for new Mock<T>
kzu Jul 23, 2019
a58ad2d
Setup should happen as soon as possible
kzu Jul 23, 2019
72a1a28
Make sure we use the test calling assembly
adalon Jul 24, 2019
df46b70
Added SkipBehavior support for behavior pipeline
adalon Jul 24, 2019
5aaca90
Add new behavior for setup scope runs
kzu Jul 24, 2019
0c2ff79
Add setup overloads to avoid the mock T argument
kzu Jul 24, 2019
60237fe
Added AsMoq extension method
adalon Jul 24, 2019
eda348b
Simplify Behavior implementation by using SkipBehaviors
kzu Jul 24, 2019
edc7b68
Revert "Add setup overloads to avoid the mock T argument"
kzu Jul 24, 2019
efeefc3
Fix failing tests
kzu Jul 24, 2019
4e9d640
Move setup scope to Moq
kzu Jul 24, 2019
004e96e
Fix visiblity of various Sdk-like classes in the Moq main assembly
kzu Jul 24, 2019
91b4853
Added CallBase support
adalon Jul 24, 2019
58a67fe
Don't run FixupImports twice
kzu Jul 25, 2019
3f191e7
Ensure both analyzers and codefixers have NuGetPackageId metadata
kzu Jul 25, 2019
4c5db10
Optimize codegen performance for real world solutions
kzu Jul 25, 2019
e159b48
Do not clean unused namespaces, since it is costly for little benefit
kzu Jul 25, 2019
814afdc
Bump to latest Roslyn for VS2017 and updated supported code fix names
kzu Jul 25, 2019
708db5b
Ensure a clean restore is performed always, add CI feed
kzu Jul 25, 2019
20b9fd2
Set proper names for CallBase tests
adalon Jul 25, 2019
6143a8a
Bump TFV to the 16.0+ official one supporting NS2
kzu Jul 29, 2019
e5b1c4e
Properly generate code for generic mocks
kzu Aug 3, 2019
d9bbc2e
Add support for mocking generic types
kzu Aug 6, 2019
34a6c49
Move OverrideAllMembersCodeFix to CodeFix assembly to avoid csc error
kzu Aug 6, 2019
1e97239
Don't assume mocked types will be public
kzu Aug 6, 2019
e30d526
Cleanup and encapsulate the batch code fixer and avoid state capturing
kzu Aug 6, 2019
f4b4be4
Delete OverrideAllMembersCodeFix class that moved to CodeFix
kzu Aug 6, 2019
d5e5fd7
Re-enable end to end tests for VB since they work now
kzu Aug 6, 2019
cfddaf2
Fix roslyn internals tests from moved RoslynInternals.cs file
kzu Aug 8, 2019
2e4f6e8
Fix minor style issues flagged by codefactor.io
kzu Aug 8, 2019
462cf05
Unify naming conventions for runtime lookup
kzu Aug 8, 2019
83a22b0
Minor docs tweaks to CallBase
kzu Aug 8, 2019
db87731
Drastically simplify As<T> support by adding new Mock<T...Tn>
kzu Aug 8, 2019
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
Prev Previous commit
Next Next commit
Move OverrideAllMembersCodeFix to CodeFix assembly to avoid csc error
This code fix should only load in our own workspace, since csc does not contain the
required dependencies for it to load properly. This was causing transient build errors
when csc.exe would try to inspect the types via MEF and fail in the static initialization
of the RoslynInternals class which even if not used since the code fix was not exported,
was nevertheless initialized statically when reflected by the MEF composition.

By moving it to the CodeFix assembly, we also make it work transparently like all other
code fixers, which are referenced just by name. We were already doing that from the
C# and VB scaffold document processors, so no changes were necessary there.
  • Loading branch information
kzu committed Aug 6, 2019
commit 34a6c49538d786e98cb24e3d73366895b0fea1cf
1 change: 1 addition & 0 deletions src/Moq/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Stunts\Stunts.CodeFix\Stunts.CodeFix.csproj" />
<ProjectReference Include="..\Moq.Sdk\Moq.Sdk.csproj" />
<ProjectReference Include="..\..\Stunts\Stunts\Stunts.csproj" />
<ProjectReference Include="..\..\Stunts\Stunts.Sdk\Stunts.Sdk.csproj" />
Expand Down
28 changes: 28 additions & 0 deletions src/Moq/Moq.Tests/LegacyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using Xunit;

namespace Moq.Tests
{
public class LegacyTests
{
[Fact]
public void AsInterface()
{
var sp = new Mock<IServiceProvider>();

sp.Setup(x => x.GetService(typeof(IDisposable))).Returns(Mock.Of<IDisposable>());

sp.As<IDisposable>()
.Setup(x => x.Dispose())
.Callback(() => Assert.False(true, "Callback"));

Assert.NotNull(sp.Object.GetService(typeof(IDisposable)));

var disposable = sp.Object as IDisposable;

Assert.NotNull(disposable);

disposable.Dispose();
}
}
}
69 changes: 69 additions & 0 deletions src/Stunts/Stunts.CodeFix/OverrideAllMembersCodeFix.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Editing;

namespace Stunts
{
/// <summary>
/// Implements the codefix for overriding all members in a class
/// using <see cref="RoslynInternals.OverrideAsync"/>.
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, new[] { LanguageNames.VisualBasic }, Name = nameof(OverrideAllMembersCodeFix))]
class OverrideAllMembersCodeFix : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(OverridableMembersAnalyzer.DiagnosticId);

public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
var diagnostic = context.Diagnostics.FirstOrDefault(d => FixableDiagnosticIds.Contains(d.Id));
if (diagnostic == null)
return;

var sourceToken = root.FindToken(diagnostic.Location.SourceSpan.Start);

// Find the invocation identified by the diagnostic.
var type =
(SyntaxNode)sourceToken.Parent.AncestorsAndSelf().OfType<Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax>().FirstOrDefault() ??
(SyntaxNode)sourceToken.Parent.AncestorsAndSelf().OfType<Microsoft.CodeAnalysis.VisualBasic.Syntax.ClassBlockSyntax>().FirstOrDefault();

context.RegisterCodeFix(
CodeAction.Create(
title: "Override All Members",
createChangedSolution: c => OverrideAllMembersAsync(context.Document, type, c),
equivalenceKey: nameof(OverrideAllMembersCodeFix)),
diagnostic);
}

async Task<Solution> OverrideAllMembersAsync(Document document, SyntaxNode type, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
var symbol = semanticModel.GetDeclaredSymbol(type) as INamedTypeSymbol;
if (symbol == null)
return document.Project.Solution;

var overridables = RoslynInternals.GetOverridableMembers(symbol, cancellationToken);

if (type.Language == LanguageNames.VisualBasic)
overridables = overridables
.Where(x => x.MetadataName != WellKnownMemberNames.DestructorName)
// VB doesn't support overriding events (yet). See https://github.com/dotnet/vblang/issues/63
.Where(x => x.Kind != SymbolKind.Event)
.ToImmutableArray();

var generator = SyntaxGenerator.GetGenerator(document);
var memberTasks = overridables.Select(
m => RoslynInternals.OverrideAsync(generator, m, symbol, document, cancellationToken: cancellationToken));

var members = await Task.WhenAll(memberTasks);
var newDoc = await RoslynInternals.AddMemberDeclarationsAsync(document.Project.Solution, symbol, members, cancellationToken);

return newDoc.Project.Solution;
}
}
}
4 changes: 4 additions & 0 deletions src/Stunts/Stunts.CodeFix/Stunts.CodeFix.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<AdditionalProperties>PrimaryOutputKind=$(PrimaryOutputKind);IncludeApi=false</AdditionalProperties>
</ProjectReference>
</ItemDefinitionGroup>

<ItemGroup>
<Compile Include="..\Stunts.Sdk\RoslynInternals.cs" Link="RoslynInternals.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Stunts\Stunts.csproj" />
Expand Down
1 change: 0 additions & 1 deletion src/Stunts/Stunts.CodeFix/Stunts.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@
</Compile>
</ItemGroup>


</Project>
3 changes: 1 addition & 2 deletions src/Stunts/Stunts.Sdk/DocumentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ await provider.RegisterCodeFixesAsync(
// Debug view of all available providers and their metadata
// document.Project.Solution.Workspace.Services.HostServices.GetExports<CodeFixProvider, IDictionary<string, object>>().OrderBy(x => x.Metadata["Name"]?.ToString()).Select(x => $"{x.Metadata["Name"]}: {string.Join(", ", (string[])x.Metadata["Languages"])}" ).ToList()
static CodeFixProvider GetCodeFixProvider(Document document, string codeFixName)
=> codeFixName == nameof(OverrideAllMembersCodeFix) ? new OverrideAllMembersCodeFix() :
document.Project.Solution.Workspace.Services.HostServices
=> document.Project.Solution.Workspace.Services.HostServices
.GetExports<CodeFixProvider, IDictionary<string, object>>()
.Where(x =>
x.Metadata.ContainsKey("Languages") && x.Metadata.ContainsKey("Name") &&
Expand Down
9 changes: 6 additions & 3 deletions src/Stunts/Stunts.Tests/DynamicStunt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@

namespace Stunts.Tests
{
class DynamicStunt
class DynamicStunt : IDisposable
{
StuntGenerator generator = new StuntGenerator();
Workspace workspace;
Project project;
readonly string language;

Expand Down Expand Up @@ -53,8 +54,8 @@ async Task<Project> GetProjectAsync()
{
if (project == null)
{
var (workspace, project) = CreateWorkspaceAndProject(language);
this.project = project.AddAnalyzerReference(new AnalyzerImageReference(new DiagnosticAnalyzer[] { new OverridableMembersAnalyzer() }.ToImmutableArray()));
(workspace, project) = CreateWorkspaceAndProject(language);
project = project.AddAnalyzerReference(new AnalyzerImageReference(new DiagnosticAnalyzer[] { new OverridableMembersAnalyzer() }.ToImmutableArray()));
var compilation = await project.GetCompilationAsync(TimeoutToken(5));

Assert.False(compilation.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error),
Expand All @@ -73,5 +74,7 @@ static ITypeSymbol GetSymbolFromType(Compilation compilation, Type type)
.GetTypeByMetadataName(type.GetGenericTypeDefinition().FullName)
.Construct(type.GenericTypeArguments.Select(t => GetSymbolFromType(compilation, t)).ToArray());
}

public void Dispose() => workspace.Dispose();
}
}
4 changes: 1 addition & 3 deletions src/Stunts/Stunts.Tests/Stunts.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,10 @@
<ItemGroup>
<Compile Include="..\..\Moq\Moq.Sdk\DefaultValueBehavior.cs" Link="DefaultValueBehavior.cs" />
<Compile Include="..\..\Moq\Moq.Sdk\DefaultValueProvider.cs" Link="DefaultValueProvider.cs" />
<None Include="..\Stunts.Sdk\RoslynInternals.cs" Link="RoslynInternals.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Stunts.CodeFix\Stunts.CodeFix.csproj" />
<ProjectReference Include="..\Stunts\Stunts.csproj" />
<ProjectReference Include="..\Stunts.Sdk\Stunts.Sdk.csproj" />
<ProjectReference Include="..\..\Samples\Sample\Sample.csproj" />
Expand Down
52 changes: 0 additions & 52 deletions src/Stunts/Stunts.Tests/SymbolExtensionsTests.cs

This file was deleted.

4 changes: 3 additions & 1 deletion src/Testing/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.VisualBasic;
using Stunts;
using Xunit;

static partial class TestHelpers
{
public static (AdhocWorkspace workspace, Project project) CreateWorkspaceAndProject(string language, string assemblyName = "Code", bool includeStuntApi = true, bool includeMockApi = false)
{
var workspace = new AdhocWorkspace();
var workspace = new AdhocWorkspace(MefHostServices.Create(MefHostServices.DefaultAssemblies.Concat(new[] { typeof(StuntCodeFixProvider).Assembly })));
var projectInfo = CreateProjectInfo(language, assemblyName, includeStuntApi, includeMockApi);
var project = workspace.AddProject(projectInfo);

Expand Down
6 changes: 6 additions & 0 deletions src/build/Settings.props
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
<None Remove="*.binlog" />
</ItemGroup>

<ItemDefinitionGroup>
<PackageReference>
<GeneratePathProperty>true</GeneratePathProperty>
</PackageReference>
</ItemDefinitionGroup>

<!-- IsTestProject is set by xunit -->
<Import Project="Settings.Tests.props" Condition="'$(IsTestProject)' == 'true'" />

Expand Down