Skip to content

Commit

Permalink
Merge branch 'main' into feature/UpdateDocumentation
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/MiniMock/Builders/Helpers.cs
  • Loading branch information
oswaldsql committed Nov 2, 2024
2 parents be74010 + 3fddd9c commit 07e0083
Show file tree
Hide file tree
Showing 21 changed files with 145 additions and 153 deletions.
2 changes: 1 addition & 1 deletion src/MiniMock/AnalyzerReleases.Shipped.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Rule ID | Category | Severity | Notes
--------|----------|----------|--------------------
MM0002 | Usage | Error | Ref properties not supported, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0002.md)
MM0003 | Usage | Error | Ref return type not supported, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0003.md)
MM0004 | Usage | Error | Generic method not supported, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0004.md)
MM0004 | Usage | Error | Generic method not supported, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0004.md)
MM0005 | Usage | Error | Static abstract members not supported, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0005.md)
MM0006 | Usage | Error | Can not create mock for a sealed class, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0006.md)

6 changes: 5 additions & 1 deletion src/MiniMock/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
### New Rules
### Removed Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|--------------------
MM0004 | Usage | Error | Generic method not supported, [Documentation](https://github.com/oswaldsql/MiniMock/blob/main/Documentation/AnalyzerRules/MM0004.md)
12 changes: 6 additions & 6 deletions src/MiniMock/Builders/EventBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ private static void BuildEvent(CodeBuilder builder, IEventSymbol symbol, List<Me

builder.Add($$"""
private event {{typeSymbol}}? {{eventFunction}};
private event {{typeSymbol}}? _{{eventFunction}};
{{accessibilityString}} event {{typeSymbol}}? {{containingSymbol}}{{eventName}}
{
add => this.{{eventFunction}} += value;
remove => this.{{eventFunction}} -= value;
add => this._{{eventFunction}} += value;
remove => this._{{eventFunction}} -= value;
}
private void trigger_{{eventFunction}}({{parameterList}})
{
{{eventFunction}}?.Invoke({{nameList}});
_{{eventFunction}}?.Invoke({{nameList}});
}
""");
Expand All @@ -86,8 +86,8 @@ private static void BuildEvent(CodeBuilder builder, IEventSymbol symbol, List<Me
$"trigger = args => this.{eventName}(args);",
$"Returns an action that can be used for triggering {eventName}.", seeCref));

helpers.Add(new(types + " eventArgs",
$"target.trigger_{eventFunction}(target, eventArgs);",
helpers.Add(new(types + " raise",
$"target.trigger_{eventFunction}(target, raise);",
$"Trigger {eventName} directly.", seeCref));
}
}
Expand Down
24 changes: 11 additions & 13 deletions src/MiniMock/Builders/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static string AccessibilityString(this Accessibility accessibility) =>
Accessibility.Protected => "protected",
Accessibility.ProtectedOrInternal => "protected internal",
Accessibility.Public => "public",
_ => throw new UnsupportedAccessibilityException(accessibility)
_ => throw new UnsupportedAccessibilityException(accessibility),
};

internal static void BuildHelpers(this List<MethodSignature> helpers, CodeBuilder builder, string name)
Expand All @@ -44,21 +44,19 @@ internal static void BuildHelpers(this List<MethodSignature> helpers, CodeBuilde

foreach (var grouping in signatures)
{
builder.Add($"""
/// <summary>
""");
builder.Add("""/// <summary>""");

grouping.Select(t => t.Documentation).Where(t => !string.IsNullOrWhiteSpace(t)).Distinct().ToList().ForEach(t => builder.Add("/// " + t));
if (grouping.Any(t => t.SeeCref != ""))
{
var crefs = grouping.Select(t => t.SeeCref).Where(t => !string.IsNullOrWhiteSpace(t)).Select(t => $" - <see cref=\"{t.EscapeToHtml()}\" />");
builder.Add("///<br/> Applies to <br/>" + string.Join("<br/>", crefs));
var crefs = grouping.Select(t => t.SeeCref).Where(t => !string.IsNullOrWhiteSpace(t)).Select(t => $"<see cref=\"{t.EscapeToHtml()}\" />");
builder.Add("/// Configures " + string.Join(", ", crefs));
}

builder.Add($"""
/// </summary>
/// <returns>The configured for further chaining.</returns>
""");
builder.Add("""
/// </summary>
/// <returns>The updated configuration.</returns>
""");

builder.Add($"public Config {name}({grouping.Key}) {{").Indent();
foreach (var mse in grouping)
Expand All @@ -74,14 +72,14 @@ internal static void BuildHelpers(this List<MethodSignature> helpers, CodeBuilde
builder.Unindent().Add("}");
}

internal static string OutString(this IParameterSymbol parameterSymbol) =>
internal static string OutAsString(this IParameterSymbol parameterSymbol) =>
parameterSymbol.RefKind switch
{
RefKind.Out => "out ",
RefKind.Ref => "ref ",
RefKind.In => "in ",
RefKind.RefReadOnlyParameter => "ref readonly ",
_ => ""
_ => "",
};

internal static bool HasParameters(this IMethodSymbol method) => method.Parameters.Length > 0;
Expand Down Expand Up @@ -112,7 +110,7 @@ internal static (string containingSymbol, string accessibilityString, string ove

internal static (string methodParameters, string parameterList, string typeList, string nameList) ParameterStrings(this IMethodSymbol method)
{
var parameters = method.Parameters.Select(t => new ParameterInfo(t.Type.ToString(), t.Name, t.OutString(), t.Name)).ToList();
var parameters = method.Parameters.Select(t => new ParameterInfo(t.Type.ToString(), t.Name, t.OutAsString(), t.Name)).ToList();

var methodParameters = parameters.ToString(p => $"{p.OutString}{p.Type} {p.Name}");

Expand Down
5 changes: 0 additions & 5 deletions src/MiniMock/Builders/PropertyBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ public static void BuildProperties(CodeBuilder builder, IEnumerable<IPropertySym
{
if (symbol.IsStatic)
{
if (symbol.IsAbstract)
{
throw new StaticAbstractMembersNotSupportedException(name, symbol.ContainingType);
}

builder.Add($"// Ignoring Static property {symbol}.");
}else if (!symbol.IsAbstract && !symbol.IsVirtual)
{
Expand Down
10 changes: 0 additions & 10 deletions src/MiniMock/DiagnosticsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ public static void AddRefReturnTypeNotSupported(this SourceProductionContext con
}
}


private static readonly DiagnosticDescriptor Mm0004 = new("MM0004", "Unsupported feature", "{0}", "Usage", DiagnosticSeverity.Error, true);
public static void AddGenericMethodNotSupported(this SourceProductionContext context, IEnumerable<Location> locations, string message)
{
foreach (var l in locations)
{
context.ReportDiagnostic(Diagnostic.Create(Mm0004, l, message));
}
}

private static readonly DiagnosticDescriptor Mm0005 = new("MM0005", "Unsupported feature", "{0}", "Usage", DiagnosticSeverity.Error, true);
public static void AddStaticAbstractMembersNotSupported(this SourceProductionContext context, IEnumerable<Location> locations, string message)
{
Expand Down
5 changes: 0 additions & 5 deletions src/MiniMock/MiniMockGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ private void Build(SourceProductionContext context, ImmutableArray<AttributeData
{
context.AddRefReturnTypeNotSupported(GetSourceLocations(source), e.Message);
}
catch (GenericMethodNotSupportedException e)
{
context.AddGenericMethodNotSupported(GetSourceLocations(source), e.Message);
}
catch (StaticAbstractMembersNotSupportedException e)
{
context.AddStaticAbstractMembersNotSupported(GetSourceLocations(source), e.Message);
Expand Down Expand Up @@ -86,6 +82,5 @@ private IEnumerable<AttributeData> GetAttributes(GeneratorAttributeSyntaxContext
internal class UnsupportedAccessibilityException(Accessibility accessibility) : Exception($"Unsupported accessibility type '{accessibility}'");
internal class RefPropertyNotSupportedException(IPropertySymbol propertySymbol, ITypeSymbol typeSymbol) : Exception($"Ref property not supported for '{propertySymbol.Name}' in '{typeSymbol.Name}'" );
internal class RefReturnTypeNotSupportedException(IMethodSymbol methodSymbol, ITypeSymbol typeSymbol) : Exception($"Ref return type not supported for '{methodSymbol.Name}' in '{typeSymbol.Name}'" );
internal class GenericMethodNotSupportedException(IMethodSymbol methodSymbol, ITypeSymbol typeSymbol) : Exception($"Generic methods in non generic interfaces or classes is not currently supported for '{methodSymbol.Name}' in '{typeSymbol.Name}'" );
internal class StaticAbstractMembersNotSupportedException(string name, ITypeSymbol typeSymbol) : Exception($"Static abstract members in interfaces or classes is not supported for '{name}' in '{typeSymbol.Name}'" );
internal class CanNotMockASealedClassException(ITypeSymbol typeSymbol) : Exception($"Cannot mock the sealed class '{typeSymbol.Name}'" );
3 changes: 2 additions & 1 deletion tests/MiniMock.Tests/Demo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// ReSharper disable UnusedParameter.Local
// ReSharper disable UnusedVariable
// ReSharper disable RedundantLambdaParameterType
namespace MiniMock.Tests;

using Xunit.Abstractions;
Expand Down Expand Up @@ -46,7 +47,7 @@ public async Task TestingAllTheOptions()
.Indexer(get: key => new Version(2, 0, 0, 0), set: (key, value) => { }) // Overwrites the indexer getter and setter
.Indexer(values: versions) // Provides a dictionary to retrieve and store versions

.NewVersionAdded(eventArgs: new Version(2, 0, 0, 0)) // Raises the event right away
.NewVersionAdded(raise: new Version(2, 0, 0, 0)) // Raises the event right away
.NewVersionAdded(trigger: out triggerNewVersionAdded) // Provides a trigger for when a new version is added
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
public class TriggerEventFromConfiguration
{
[Fact]
[Mock<INotifyDTO>]
[Mock<INotifyDto>]
public void ItShouldBePossibleToTriggerEventsFromConfiguration()
{
// arrange
var actual = "";
var sut = Mock.INotifyDTO(config => config.Value(() => "test", _ =>
var sut = Mock.INotifyDto(config => config.Value(() => "test", _ =>
{
config.PropertyChanged(new PropertyChangedEventArgs("Value"));
}));
Expand All @@ -25,7 +25,7 @@ public void ItShouldBePossibleToTriggerEventsFromConfiguration()
}

[Fact]
[Mock<INotifyDTO>]
[Mock<INotifyDto>]
public void ItShouldBePossibleToTriggerEventsFromAExposedConfiguration()
{
// Arrange
Expand All @@ -44,7 +44,7 @@ public void ItShouldBePossibleToTriggerEventsFromAExposedConfiguration()
Assert.Equal(new Version(2, 0, 0, 0), actual);
}

public interface INotifyDTO : INotifyPropertyChanged
public interface INotifyDto : INotifyPropertyChanged
{
public string Value { get; set; }
}
Expand Down
56 changes: 46 additions & 10 deletions tests/MiniMock.Tests/GeneralTests/AbstractClassesTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace MiniMock.Tests.GeneralTests;

using Xunit.Sdk;

public class AbstractClassesTest
{
public abstract class AbstractClass
Expand All @@ -8,27 +10,30 @@ public abstract class AbstractClass
public abstract string Abstract { get; set; }
public virtual string Virtual { get; set; } = "";

public string NotAbstractGetOnly { get; } = "";
public string NotAbstractGetOnly => this.abstractValue ?? "";
public abstract string AbstractGetOnly { get; }
public virtual string VirtualGetOnly { get; } = "";
public virtual string VirtualGetOnly => throw new TestClassException("this should never be called");

public string NotAbstractSetOnly { set { } }
private string? abstractValue;
public string NotAbstractSetOnly { set => this.abstractValue = value; }
public abstract string AbstractSetOnly { set; }
public virtual string VirtualSetOnly { set{} }
public virtual string VirtualSetOnly { set => throw new TestClassException("this should never be called"); }
}

[Fact]
[Mock<AbstractClass>]
public void AbstractClassPropertiesCanBeSet()
{
// Arrange
string? actualVirtualSetOnly = null;

var sut = Mock.AbstractClass(config => config
.Abstract("Abstract")
.AbstractGetOnly("AbstractGetOnly")
.AbstractSetOnly("AbstractSetOnly")
.Virtual("Virtual")
.VirtualGetOnly("VirtualGetOnly")
.VirtualSetOnly("VirtualSetOnly")
.VirtualSetOnly(set: s => actualVirtualSetOnly = s)
);

// ACT
Expand All @@ -41,26 +46,57 @@ public void AbstractClassPropertiesCanBeSet()
Assert.Equal("Virtual",sut.Virtual);
Assert.Equal("VirtualGetOnly",sut.VirtualGetOnly);
sut.VirtualSetOnly = "VirtualSetOnly";
Assert.Equal("VirtualSetOnly", actualVirtualSetOnly);
}

[Fact]
[Mock<AbstractClass>]
public void NoneAbstractClassPropertiesAreParsedThroughToTheBaseClass()
{
// Arrange
var sut = Mock.AbstractClass();

// ACT
sut.NotAbstract = "test";
var sutNotAbstractGetOnly = sut.NotAbstractGetOnly;
sut.NotAbstractSetOnly = "test";

// Assert
Assert.Equal("test", sut.NotAbstract);
Assert.Equal("",sutNotAbstractGetOnly);
}

[Fact]
[Mock<AbstractClass>]
public void AbstractClassPropertiesFunctionsCanBeSet()
{
string? actualAbstract = null;
string? actualAbstractSetOnly = null;
string? actualVirtual = null;
string? actualVirtualSetOnly = null;
// Arrange
var sut = Mock.AbstractClass(config => config
.Abstract(get: () => "Abstract", set:s => {})
.Abstract(get: () => "Abstract", set:s => actualAbstract = s)
.AbstractGetOnly(get: () => "AbstractGetOnly")
.AbstractSetOnly(set: s => { })
.Virtual(get: () => "Virtual", set: s => {})
.AbstractSetOnly(set: s => actualAbstractSetOnly = s)
.Virtual(get: () => "Virtual", set: s => actualVirtual = s)
.VirtualGetOnly(get:() => "VirtualGetOnly")
.VirtualSetOnly(set : s => {})
.VirtualSetOnly(set : s => actualVirtualSetOnly = s)
);

// ACT

sut.Abstract = "setAbstract";
sut.AbstractSetOnly = "setAbstractSetOnly";
sut.Virtual = "setVirtual";
sut.VirtualSetOnly = "setVirtualSetOnly";

// Assert
Assert.Equal("setAbstract",actualAbstract);
Assert.Equal("setAbstractSetOnly",actualAbstractSetOnly);
Assert.Equal("setVirtual",actualVirtual);
Assert.Equal("setVirtualSetOnly",actualVirtualSetOnly);


Assert.Equal("Abstract",sut.Abstract);
Assert.Equal("AbstractGetOnly",sut.AbstractGetOnly);
sut.AbstractSetOnly = "AbstractSetOnly";
Expand Down
4 changes: 2 additions & 2 deletions tests/MiniMock.Tests/IndexerTests/GenericIndexerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

public class GenericIndexerTests
{
public interface IGenericIndexRepository<in T, U> where U : new() where T : notnull
public interface IGenericIndexRepository<in T, TU> where TU : new() where T : notnull
{
U this[T index] { get; set; }
TU this[T index] { get; set; }
}

[Fact]
Expand Down
9 changes: 3 additions & 6 deletions tests/MiniMock.Tests/IndexerTests/StaticInterfaceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ public class StaticInterfaceTests
{
public interface ISupportedStaticInterfaceMembers
{
static ISupportedStaticInterfaceMembers(){}
static ISupportedStaticInterfaceMembers() => StaticProperty = "Set from ctor";

static int StaticProperty { get; set; }
static string StaticProperty { get; set; }
static string StaticMethod() => "value";
static event EventHandler? StaticEvent;

static void DoStaticEvent()
{
StaticEvent?.Invoke(null, EventArgs.Empty);
}
static void DoStaticEvent() => StaticEvent?.Invoke(null, EventArgs.Empty);

static virtual string Bar => "value"; // with implementation
}
Expand Down
Loading

0 comments on commit 07e0083

Please sign in to comment.