Normalize mocking in mgc.tests (#3807)

We were all doing mocking slightly differently. I created a common
helper to mock the plugin and provide some functionality to pass in
behaviors that we want to change on a per test basis. I will make a
follow up PR to update mgc.cm to follow the same pattern.
This commit is contained in:
m-nash 2024-07-10 12:48:35 -07:00 коммит произвёл GitHub
Родитель 737f244f0b
Коммит 22ac8af723
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
22 изменённых файлов: 117 добавлений и 320 удалений

Просмотреть файл

@ -14,8 +14,6 @@ namespace Microsoft.Generator.CSharp.Tests
{
public class CSharpGenTests
{
private readonly string _mocksFolder = "./Mocks";
// Validates that the output path is parsed correctly when provided
[Test]
public void TestGetOutputPath_OutputPathProvided()
@ -48,7 +46,7 @@ namespace Microsoft.Generator.CSharp.Tests
public void TestCSharpGen_ValidPlugin()
{
// mock plugin
var mockPlugin = new Mock<CodeModelPlugin>(new GeneratorContext(Configuration.Load(_mocksFolder)))
var mockPlugin = new Mock<CodeModelPlugin>(new GeneratorContext(Configuration.Load(MockHelpers.MocksFolder)))
{
CallBase = true
};
@ -62,7 +60,7 @@ namespace Microsoft.Generator.CSharp.Tests
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(new CSharpType(typeof(IList<>)));
mockPlugin.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
var configFilePath = Path.Combine(_mocksFolder, "Configuration.json");
var configFilePath = Path.Combine(MockHelpers.MocksFolder, "Configuration.json");
var csharpGen = new CSharpGen().ExecuteAsync();
Assert.IsNotNull(csharpGen);

Просмотреть файл

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using Moq;
using NUnit.Framework;
namespace Microsoft.Generator.CSharp.Tests
@ -12,9 +11,6 @@ namespace Microsoft.Generator.CSharp.Tests
// Tests for the Configuration class
public class ConfigurationTests
{
#pragma warning disable CS8602 // Dereference of a possibly null reference.
private readonly string _mocksFolder = "./Mocks";
// Validates that the configuration is initialized correctly given input
[Test]
public void TestInitialize()
@ -23,7 +19,7 @@ namespace Microsoft.Generator.CSharp.Tests
string? unknownStringProperty = "unknownPropertyValue";
bool? unknownBoolProp = false;
var configuration = Configuration.Load(_mocksFolder);
var configuration = Configuration.Load(MockHelpers.MocksFolder);
var parsedNs = configuration.RootNamespace;
@ -45,7 +41,7 @@ namespace Microsoft.Generator.CSharp.Tests
[Test]
public void TestInitialize_NoFileFound()
{
var configFilePath = Path.Combine(_mocksFolder, "unknown_file.out");
var configFilePath = Path.Combine(MockHelpers.MocksFolder, "unknown_file.out");
Assert.Throws<InvalidOperationException>(() => Configuration.Load(configFilePath));
}
@ -54,7 +50,7 @@ namespace Microsoft.Generator.CSharp.Tests
public void TestParseConfig_OutputFolder(string mockJson, bool throwsError)
{
var expected = Path.GetFullPath(_mocksFolder);
var expected = Path.GetFullPath(MockHelpers.MocksFolder);
if (throwsError)
{
@ -62,7 +58,7 @@ namespace Microsoft.Generator.CSharp.Tests
return;
}
var configuration = Configuration.Load(_mocksFolder, mockJson);
var configuration = Configuration.Load(MockHelpers.MocksFolder, mockJson);
Assert.AreEqual(expected, configuration.OutputDirectory);
}

Просмотреть файл

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.IO;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Providers;
@ -15,17 +13,9 @@ namespace Microsoft.Generator.CSharp.Tests.Expressions
{
internal class ExpressionsTests
{
private readonly string _mocksFolder = "Mocks";
[OneTimeSetUp]
public void Setup()
public ExpressionsTests()
{
string outputFolder = "./outputFolder";
string projectPath = outputFolder;
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
_ = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
MockHelpers.LoadMockPlugin();
}
[Test]

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Providers;
@ -11,8 +10,6 @@ namespace Microsoft.Generator.CSharp.Tests
{
internal class MockCodeModelPlugin : CodeModelPlugin
{
private static readonly string _mocksFolder = "Mocks";
public MockCodeModelPlugin(GeneratorContext context)
: base(context)
{
@ -22,14 +19,5 @@ namespace Microsoft.Generator.CSharp.Tests
public override OutputLibrary OutputLibrary => throw new NotImplementedException();
public override IReadOnlyList<TypeProvider> GetSerializationTypeProviders(TypeProvider provider, InputType inputModel) => throw new NotImplementedException();
public override string LicenseString => "// License string";
internal static void LoadMockPlugin()
{
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
var mockPlugin = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
Instance = mockPlugin;
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.IO;
using System;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Primitives;
using Moq.Protected;
using Moq;
namespace Microsoft.Generator.CSharp.Tests
{
internal static class MockHelpers
{
public const string MocksFolder = "Mocks";
public static void LoadMockPlugin(Func<InputType, CSharpType>? createCSharpTypeCore = null)
{
var configFilePath = Path.Combine(AppContext.BaseDirectory, MocksFolder);
// initialize the singleton instance of the plugin
var mockPlugin = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
var mockPluginInstance = new Mock<CodeModelPlugin>(new GeneratorContext(Configuration.Load(configFilePath)));
var mockTypeFactory = new Mock<TypeFactory>();
if (createCSharpTypeCore != null)
{
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns((InputType inputType) => createCSharpTypeCore.Invoke(inputType));
}
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
CodeModelPlugin.Instance = mockPlugin;
}
}
}

Просмотреть файл

@ -8,6 +8,8 @@ namespace Microsoft.Generator.CSharp.Tests
{
internal class MockTypeProvider : TypeProvider
{
public static readonly TypeProvider Empty = new MockTypeProvider();
public override string RelativeFilePath => throw new NotImplementedException();
public override string Name => throw new NotImplementedException();
}

Просмотреть файл

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Generator.CSharp.Primitives;
@ -14,14 +13,9 @@ namespace Microsoft.Generator.CSharp.Tests.Primitives
{
internal class CSharpTypeTests
{
private readonly string _mocksFolder = "Mocks";
[OneTimeSetUp]
public void Setup()
public CSharpTypeTests()
{
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
_ = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
MockHelpers.LoadMockPlugin();
}
[TestCase(typeof(int))]

Просмотреть файл

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
@ -13,17 +11,11 @@ namespace Microsoft.Generator.CSharp.Tests.Primitives
{
internal class KnownParametersTests
{
private readonly string _mocksFolder = "Mocks";
[OneTimeSetUp]
public void OneTimeSetup()
public KnownParametersTests()
{
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
_ = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
MockHelpers.LoadMockPlugin();
}
[Test]
public void TestCancellationToken()
{

Просмотреть файл

@ -1,18 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Providers;
using Microsoft.Generator.CSharp.Snippets;
using Moq;
using Moq.Protected;
using NUnit.Framework;
namespace Microsoft.Generator.CSharp.Tests.Providers
@ -21,35 +16,11 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
{
internal const string NewLine = "\n";
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private GeneratorContext _generatorContext;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private readonly string _configFilePath = Path.Combine(AppContext.BaseDirectory, "Mocks");
private FieldInfo? _mockPlugin;
[SetUp]
public void Setup()
{
// initialize the mock singleton instance of the plugin
_mockPlugin = typeof(CodeModelPlugin).GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic);
_generatorContext = new GeneratorContext(Configuration.Load(_configFilePath));
}
[TearDown]
public void Teardown()
{
_mockPlugin?.SetValue(null, null);
}
// Validates the int based fixed enum
[TestCase]
public void BuildEnumType_ValidateIntBasedFixedEnum()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext);
var mockTypeFactory = new Mock<TypeFactory>();
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(typeof(int));
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => typeof(int));
var input = new InputEnumType("mockInputEnum", "mockNamespace", "public", null, "The mock enum", InputModelTypeUsage.RoundTrip, new InputPrimitiveType(InputPrimitiveTypeKind.Int32), [new InputEnumTypeValue("One", 1, null), new InputEnumTypeValue("Two", 2, null)], false);
var enumType = EnumProvider.Create(input);
@ -90,11 +61,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[TestCase]
public void BuildEnumType_ValidateFloatBasedFixedEnum()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext);
var mockTypeFactory = new Mock<TypeFactory>() { };
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(typeof(float));
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => typeof(float));
var input = new InputEnumType("mockInputEnum", "mockNamespace", "public", null, "The mock enum", InputModelTypeUsage.RoundTrip, new InputPrimitiveType(InputPrimitiveTypeKind.Float32), [new InputEnumTypeValue("One", 1f, null), new InputEnumTypeValue("Two", 2f, null)], false);
var enumType = EnumProvider.Create(input);
@ -132,11 +99,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[TestCase]
public void BuildEnumType_ValidateStringBasedFixedEnum()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext);
var mockTypeFactory = new Mock<TypeFactory>();
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(typeof(string));
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => typeof(string));
var input = new InputEnumType("mockInputEnum", "mockNamespace", "public", null, "The mock enum", InputModelTypeUsage.RoundTrip, new InputPrimitiveType(InputPrimitiveTypeKind.String), [new InputEnumTypeValue("One", "1", null), new InputEnumTypeValue("Two", "2", null)], false);
var enumType = EnumProvider.Create(input);
@ -174,11 +137,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[TestCase]
public void BuildEnumType_ValidateIntBasedExtensibleEnum()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext);
var mockTypeFactory = new Mock<TypeFactory>();
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(typeof(int));
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => typeof(int));
var input = new InputEnumType("mockInputEnum", "mockNamespace", "public", null, "The mock enum", InputModelTypeUsage.RoundTrip, new InputPrimitiveType(InputPrimitiveTypeKind.Int32), [new InputEnumTypeValue("One", 1, null), new InputEnumTypeValue("Two", 2, null)], true);
var enumType = EnumProvider.Create(input);
@ -235,11 +194,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[TestCase]
public void BuildEnumType_ValidateFloatBasedExtensibleEnum()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext);
var mockTypeFactory = new Mock<TypeFactory>();
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(typeof(float));
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => typeof(float));
var input = new InputEnumType("mockInputEnum", "mockNamespace", "public", null, "The mock enum", InputModelTypeUsage.RoundTrip, new InputPrimitiveType(InputPrimitiveTypeKind.Float32), [new InputEnumTypeValue("One", 1f, null), new InputEnumTypeValue("Two", 2f, null)], true);
var enumType = EnumProvider.Create(input);
@ -296,11 +251,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[TestCase]
public void BuildEnumType_ValidateStringBasedExtensibleEnum()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext);
var mockTypeFactory = new Mock<TypeFactory>();
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(typeof(string));
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => typeof(string));
var input = new InputEnumType("mockInputEnum", "mockNamespace", "public", null, "The mock enum", InputModelTypeUsage.RoundTrip, new InputPrimitiveType(InputPrimitiveTypeKind.String), [new InputEnumTypeValue("One", "1", null), new InputEnumTypeValue("Two", "2", null)], true);
var enumType = EnumProvider.Create(input);

Просмотреть файл

@ -3,56 +3,28 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Providers;
using Moq;
using Moq.Protected;
using NUnit.Framework;
namespace Microsoft.Generator.CSharp.Tests.Providers
{
public class ModelProviderTests
{
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private GeneratorContext _generatorContext;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private readonly string _configFilePath = Path.Combine(AppContext.BaseDirectory, "Mocks");
private FieldInfo? _mockPlugin;
[SetUp]
public void Setup()
{
// initialize the mock singleton instance of the plugin
_mockPlugin = typeof(CodeModelPlugin).GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic);
_generatorContext = new GeneratorContext(Configuration.Load(_configFilePath));
}
[TearDown]
public void Teardown()
{
_mockPlugin?.SetValue(null, null);
}
// Validates that the property body's setter is correctly set based on the property type
[TestCaseSource(nameof(BuildProperties_ValidatePropertySettersTestCases))]
public void BuildProperties_ValidatePropertySetters(InputModelProperty inputModelProperty, CSharpType type, bool hasSetter)
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext) { };
var mockTypeFactory = new Mock<TypeFactory>() { };
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns(type);
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (inputType) => type);
var props = new[]
{
inputModelProperty
};
var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, props, null, new List<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, false);
var inputModel = new InputModelType("mockInputModel", "mockNamespace", "public", null, null, InputModelTypeUsage.RoundTrip, props, null, [], null, null, new Dictionary<string, InputModelType>(), null, false);
var modelTypeProvider = new ModelProvider(inputModel);
var properties = modelTypeProvider.Properties;
@ -86,7 +58,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
yield return new TestCaseData(
new InputModelProperty("prop1", "prop1", "public", new InputArrayType("mockProp", "TypeSpec.Array", new InputPrimitiveType(InputPrimitiveTypeKind.String)), false, false, false),
new CSharpType(typeof(IList<string>), true),
true);
false);
// dictionary property
yield return new TestCaseData(
new InputModelProperty("prop1", "prop1", "public", new InputDictionaryType("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String), new InputPrimitiveType(InputPrimitiveTypeKind.String)), false, false, false),
@ -96,7 +68,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
yield return new TestCaseData(
new InputModelProperty("prop1", "prop1", "public", new InputDictionaryType("mockProp", new InputPrimitiveType(InputPrimitiveTypeKind.String), new InputPrimitiveType(InputPrimitiveTypeKind.String)), false, false, false),
new CSharpType(typeof(IDictionary<string, string>), true),
true);
false);
// primitive type property
yield return new TestCaseData(
new InputModelProperty("prop1", "prop1", "public", new InputPrimitiveType(InputPrimitiveTypeKind.String), false, false, false),
@ -111,7 +83,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
yield return new TestCaseData(
new InputModelProperty("prop1", "prop1", "public", new InputArrayType("mockProp", "TypeSpec.Array", new InputPrimitiveType(InputPrimitiveTypeKind.String)), false, false, false),
new CSharpType(typeof(ReadOnlyMemory<>)),
true);
false);
}
}
@ -132,9 +104,6 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[Test]
public void BuildConstructor_ValidateConstructors()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext) { };
var mockTypeFactory = new Mock<TypeFactory>() { };
var properties = new List<InputModelProperty>{
new InputModelProperty("requiredString", "requiredString", "", InputPrimitiveType.String, true, false, false),
new InputModelProperty("OptionalInt", "optionalInt", "", InputPrimitiveType.Int32, false, false, false),
@ -143,7 +112,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
new InputModelProperty("optionalUnknown", "optional unknown", "", InputPrimitiveType.Any, false, false, false),
};
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns((InputType inputType) =>
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (InputType inputType) =>
{
// Lookup the inputType in the list and return the corresponding CSharpType
var inputModelProperty = properties.Where(prop => prop.Type.Name == inputType.Name).FirstOrDefault();
@ -157,9 +126,6 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
}
});
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, false);
var modelTypeProvider = new ModelProvider(inputModel);
@ -176,15 +142,12 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
[Test]
public void BuildModelAsStruct()
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext) { };
var mockTypeFactory = new Mock<TypeFactory>() { };
var properties = new List<InputModelProperty>{
new InputModelProperty("requiredString", "requiredString", "", InputPrimitiveType.String, true, false, false),
new InputModelProperty("OptionalInt", "optionalInt", "", InputPrimitiveType.Int32, false, false, false),
};
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns((InputType inputType) =>
MockHelpers.LoadMockPlugin(createCSharpTypeCore: (InputType inputType) =>
{
// Lookup the inputType in the list and return the corresponding CSharpType
var inputModelProperty = properties.Where(prop => prop.Type.Name == inputType.Name).FirstOrDefault();
@ -198,9 +161,6 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
}
});
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
var inputModel = new InputModelType("TestModel", "TestModel", "public", null, "Test model.", InputModelTypeUsage.RoundTrip, properties, null, Array.Empty<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, modelAsStruct: true);
var modelTypeProvider = new ModelProvider(inputModel);

Просмотреть файл

@ -18,7 +18,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
public NamedTypeSymbolProviderTests()
{
MockCodeModelPlugin.LoadMockPlugin();
MockHelpers.LoadMockPlugin();
List<SyntaxTree> files =
[

Просмотреть файл

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Primitives;
@ -14,7 +13,7 @@ namespace Microsoft.Generator.CSharp.Tests.Providers
{
public PropertyProviderTests()
{
MockCodeModelPlugin.LoadMockPlugin();
MockHelpers.LoadMockPlugin();
}
[Test]

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Generator.CSharp.Tests.Snippets
public ArgumentSnippetsTests()
{
MockCodeModelPlugin.LoadMockPlugin();
MockHelpers.LoadMockPlugin();
}
[Test]

Просмотреть файл

@ -13,7 +13,7 @@ namespace Microsoft.Generator.CSharp.Tests.Snippets
public ConvertSnippetsTests()
{
MockCodeModelPlugin.LoadMockPlugin();
MockHelpers.LoadMockPlugin();
}
[Test]

Просмотреть файл

@ -9,7 +9,6 @@ using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Providers;
using Microsoft.Generator.CSharp.Statements;
using Moq;
using NUnit.Framework;
using static Microsoft.Generator.CSharp.Snippets.Snippet;
@ -17,16 +16,9 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
{
public class StatementTests
{
private readonly string _mocksFolder = "Mocks";
[OneTimeSetUp]
public void Setup()
public StatementTests()
{
string outputFolder = "./outputFolder";
string projectPath = outputFolder;
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
_ = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
MockHelpers.LoadMockPlugin();
}
[Test]
@ -250,8 +242,6 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
switchStatement.Add(switchCase);
}
var mockTypeProvider = new Mock<TypeProvider>();
// Create a method declaration statement
var method = new MethodProvider(
new MethodSignature(
@ -261,7 +251,7 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
Parameters: [],
Description: null, ReturnDescription: null),
new MethodBodyStatement[] { fooDeclaration, switchStatement },
mockTypeProvider.Object);
MockTypeProvider.Empty);
// Verify the expected behavior
using var writer = new CodeWriter();
@ -294,8 +284,6 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
switchStatement.Add(switchCase);
}
var mockTypeProvider = new Mock<TypeProvider>();
// Create a method declaration statement
var method = new MethodProvider(
new MethodSignature(
@ -305,7 +293,7 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
Parameters: [],
Description: null, ReturnDescription: null),
new MethodBodyStatement[] { fooDeclaration, switchStatement },
mockTypeProvider.Object);
MockTypeProvider.Empty);
// Verify the expected behavior
using var writer = new CodeWriter();
@ -373,8 +361,6 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
CollectionAssert.AreEqual(catchStatements, tryCatchFinally.Catches);
Assert.AreEqual(finallyStatement, tryCatchFinally.Finally);
var mockTypeProvider = new Mock<TypeProvider>();
// Create a method declaration statement
var method = new MethodProvider(
new MethodSignature(
@ -384,7 +370,7 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
Parameters: [],
Description: null, ReturnDescription: null),
new MethodBodyStatement[] { tryCatchFinally },
mockTypeProvider.Object);
MockTypeProvider.Empty);
// Verify the expected behavior
using var writer = new CodeWriter();
@ -406,7 +392,6 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
var ifStatementBody = Declare(variableFoo, Int(2));
var elseStatementBody = Declare(variableBar, Int(2));
var ifElsePreprocessor = new IfElsePreprocessorStatement(condition, ifStatementBody, elseStatementBody);
var mockTypeProvider = new Mock<TypeProvider>();
// Create a method declaration statement
var method = new MethodProvider(
@ -417,7 +402,7 @@ namespace Microsoft.Generator.CSharp.Tests.Statements
Parameters: [],
Description: null, ReturnDescription: null),
new MethodBodyStatement[] { xDeclaration, ifElsePreprocessor },
mockTypeProvider.Object);
MockTypeProvider.Empty);
// Verify the expected behavior
using var writer = new CodeWriter();

Просмотреть файл

@ -12,7 +12,7 @@ namespace Microsoft.Generator.CSharp.Tests
[SetUp]
public void SetUp()
{
MockCodeModelPlugin.LoadMockPlugin();
MockHelpers.LoadMockPlugin();
}
[Test]

Просмотреть файл

@ -2,43 +2,17 @@
// Licensed under the MIT License.
using System;
using System.IO;
using System.Text;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Snippets;
using Moq;
using NUnit.Framework;
namespace Microsoft.Generator.CSharp.Tests.Writers
{
public class CodeWriterExtensionTests
{
private readonly string _mocksFolder = "Mocks";
private readonly string _licenseString = "// License string";
private readonly string _autoGenerated = "// <auto-generated/>";
private readonly string _nullableDisable = "#nullable disable";
private string? _header;
[OneTimeSetUp]
public void Setup()
public CodeWriterExtensionTests()
{
string outputFolder = "./outputFolder";
string projectPath = outputFolder;
_header = new StringBuilder()
.Append(_licenseString).Append(CodeWriterTests.NewLine)
.Append(CodeWriterTests.NewLine)
.Append(_autoGenerated).Append(CodeWriterTests.NewLine)
.Append(CodeWriterTests.NewLine)
.Append(_nullableDisable).Append(CodeWriterTests.NewLine)
.Append(CodeWriterTests.NewLine)
.ToString();
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
var mockPlugin = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
CodeModelPlugin.Instance = mockPlugin;
MockHelpers.LoadMockPlugin();
}
// Test that an exception is not thrown when the extension methods are null.
@ -59,11 +33,7 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
using var codeWriter = new CodeWriter();
castExpression.Write(codeWriter);
var sb = new StringBuilder();
sb.Append(_header);
sb.Append(expectedWritten);
Assert.AreEqual(sb.ToString(), codeWriter.ToString());
Assert.AreEqual(expectedWritten, codeWriter.ToString(false));
}
// Test the Write method for a custom expression.
@ -74,11 +44,7 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
using var codeWriter = new CodeWriter();
mockCastExpression.Write(codeWriter);
var sb = new StringBuilder();
sb.Append(_header);
sb.Append("Custom implementation");
Assert.AreEqual(sb.ToString(), codeWriter.ToString());
Assert.AreEqual("Custom implementation", codeWriter.ToString(false));
}
// Test the Write method for a CollectionInitializerExpression using the default implementation.
@ -91,11 +57,7 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
using var codeWriter = new CodeWriter();
expression.Write(codeWriter);
var sb = new StringBuilder();
sb.Append(_header);
sb.Append(expectedWritten);
Assert.AreEqual(sb.ToString(), codeWriter.ToString());
Assert.AreEqual(expectedWritten, codeWriter.ToString(false));
}
}
}

Просмотреть файл

@ -18,48 +18,20 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
public class CodeWriterTests
{
internal const string NewLine = "\n";
private CodeWriter _codeWriter = null!;
private readonly string _mocksFolder = "Mocks";
private readonly string _autoGenerated = "// <auto-generated/>";
private readonly string _nullableDisable = "#nullable disable";
private readonly string _licenseString = "License string";
private string? _header;
[SetUp]
public void Setup()
public CodeWriterTests()
{
_codeWriter = new CodeWriter();
_header = new StringBuilder()
.Append("// ")
.Append(_licenseString).Append(NewLine)
.Append(NewLine)
.Append(_autoGenerated).Append(NewLine)
.Append(NewLine)
.Append(_nullableDisable).Append(NewLine)
.Append(NewLine)
.ToString();
var configFilePath = Path.Combine(AppContext.BaseDirectory, _mocksFolder);
// initialize the singleton instance of the plugin
var mockPlugin = new MockCodeModelPlugin(new GeneratorContext(Configuration.Load(configFilePath)));
CodeModelPlugin.Instance = mockPlugin;
}
[TearDown]
public void TearDown()
{
_codeWriter?.Dispose();
MockHelpers.LoadMockPlugin();
}
[Test]
public void CorrectlyHandlesCurlyBraces()
{
_codeWriter.Append($"public {typeof(string)} Data {{ get; private set; }}");
using var writer = new CodeWriter();
writer.Append($"public {typeof(string)} Data {{ get; private set; }}");
var expected = "public string Data { get; private set; }";
Assert.AreEqual(expected, _codeWriter.ToString(false));
Assert.AreEqual(expected, writer.ToString(false));
}
[Test]
@ -68,40 +40,44 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
FormattableString fs1 = $"'1' is {typeof(int)}";
FormattableString fs2 = $"'a' is {typeof(char)} and {fs1} and 'true' is {typeof(bool)}";
_codeWriter.Append(fs2);
using var writer = new CodeWriter();
writer.Append(fs2);
var expected = "'a' is char and '1' is int and 'true' is bool";
Assert.AreEqual(expected, _codeWriter.ToString(false));
Assert.AreEqual(expected, writer.ToString(false));
}
[Test]
public void EnumerableFormatInFormat()
{
_codeWriter.Append($"Multiply:{Enumerable.Range(1, 4).Select(i => (FormattableString)$" {i} * 2 = {i * 2};")}");
using var writer = new CodeWriter();
writer.Append($"Multiply:{Enumerable.Range(1, 4).Select(i => (FormattableString)$" {i} * 2 = {i * 2};")}");
var expected = "Multiply: 1 * 2 = 2; 2 * 2 = 4; 3 * 2 = 6; 4 * 2 = 8;";
Assert.AreEqual(expected, _codeWriter.ToString(false));
Assert.AreEqual(expected, writer.ToString(false));
}
[Test]
public void SingleLineSummary()
{
using var writer = new CodeWriter();
var summary = new XmlDocSummaryStatement([$"Some {typeof(string)} summary."]);
summary.Write(_codeWriter);
summary.Write(writer);
var expected = "/// <summary> Some string summary. </summary>" + NewLine;
Assert.AreEqual(expected, _codeWriter.ToString(false));
Assert.AreEqual(expected, writer.ToString(false));
}
[Test]
public void NoEmptySummary()
{
using var writer = new CodeWriter();
var summary = new XmlDocSummaryStatement([$"{string.Empty}"]);
summary.Write(_codeWriter);
summary.Write(writer);
var expected = "/// <summary></summary>" + NewLine;
Assert.AreEqual(expected, _codeWriter.ToString(false));
Assert.AreEqual(expected, writer.ToString(false));
}
[TestCase(typeof(string), false)]
@ -112,12 +88,13 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
[TestCase(typeof(KeyValuePair<int, string>), true)]
public void SeeCRefType(Type type, bool isNullable)
{
using var writer = new CodeWriter();
var csType = new CSharpType(type).WithNullable(isNullable);
var summary = new XmlDocSummaryStatement([$"Some {csType:C} summary."]);
summary.Write(_codeWriter);
summary.Write(writer);
var expected = Helpers.GetExpectedFromFile($"{type.Name}, {isNullable}");
Assert.AreEqual(expected, _codeWriter.ToString());
Assert.AreEqual(expected, writer.ToString());
}
[Test]
@ -157,11 +134,12 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
fs.Add($"L15");
fs.Add($"L16");
using var writer = new CodeWriter();
var summary = new XmlDocSummaryStatement(fs);
summary.Write(_codeWriter);
summary.Write(writer);
var expected = Helpers.GetExpectedFromFile();
Assert.AreEqual(expected, _codeWriter.ToString());
Assert.AreEqual(expected, writer.ToString(false));
}
// Validate that the WriteMethodDeclarationNoScope method correctly writes a custom constructor signature method
@ -174,12 +152,8 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
using var codeWriter = new CodeWriter();
codeWriter.WriteMethodDeclarationNoScope(constructorSignature);
var expected = new StringBuilder()
.Append(_header)
.Append("public String(): base(\"test\")")
.ToString();
var result = codeWriter.ToString();
Assert.AreEqual(expected, result);
var result = codeWriter.ToString(false);
Assert.AreEqual("public String(): base(\"test\")", result);
}
[Test]

Просмотреть файл

@ -1,9 +1,3 @@
// License string
// <auto-generated/>
#nullable disable
/// <summary>
/// L00
/// L01

Просмотреть файл

@ -1,3 +1,5 @@
// License string
// <auto-generated/>
#nullable disable

Просмотреть файл

@ -1,3 +1,5 @@
// License string
// <auto-generated/>
#nullable disable

Просмотреть файл

@ -3,51 +3,30 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Generator.CSharp.Input;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Providers;
using Moq;
using Moq.Protected;
using NUnit.Framework;
namespace Microsoft.Generator.CSharp.Tests.Writers
{
internal class TypeProviderWriterTests
{
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private TypeProviderWriter _expressionTypeProviderWriter;
private GeneratorContext _generatorContext;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private readonly string _configFilePath = Path.Combine(AppContext.BaseDirectory, "Mocks");
private FieldInfo? _mockPlugin;
[SetUp]
public void Setup()
public TypeProviderWriterTests()
{
var mockTypeProvider = new Mock<TypeProvider>() { CallBase = true };
_expressionTypeProviderWriter = new MockExpressionTypeProviderWriter(mockTypeProvider.Object);
_mockPlugin = typeof(CodeModelPlugin).GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic);
_generatorContext = new GeneratorContext(Configuration.Load(_configFilePath));
}
[TearDown]
public void Teardown()
{
_mockPlugin?.SetValue(null, null);
MockHelpers.LoadMockPlugin();
}
// Tests that the Write method is successfully overridden.
[Test]
public void Write_Override()
{
Assert.That(_expressionTypeProviderWriter.Write, Throws.Exception.TypeOf<NotImplementedException>());
var writer = new MockExpressionTypeProviderWriter(MockTypeProvider.Empty);
Assert.That(writer.Write, Throws.Exception.TypeOf<NotImplementedException>());
}
internal class MockExpressionTypeProviderWriter : TypeProviderWriter
private class MockExpressionTypeProviderWriter : TypeProviderWriter
{
public MockExpressionTypeProviderWriter(TypeProvider provider) : base(provider) { }
@ -61,7 +40,7 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
public void TypeProviderWriter_WriteModel()
{
var properties = new List<InputModelProperty> { RequiredStringProperty, RequiredIntProperty };
MockPluginSetValue(properties);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: MockPluginSetValue(properties));
var inputModel = new InputModelType("TestModel", string.Empty, "public", null, "Test model.", InputModelTypeUsage.RoundTrip,
properties, null, new List<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, false);
@ -79,7 +58,7 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
public void TypeProviderWriter_WriteModelAsStruct()
{
var properties = new List<InputModelProperty> { RequiredStringProperty, RequiredIntProperty };
MockPluginSetValue(properties);
MockHelpers.LoadMockPlugin(createCSharpTypeCore: MockPluginSetValue(properties));
var inputModel = new InputModelType("TestModel", string.Empty, "public", null, "Test model.", InputModelTypeUsage.RoundTrip,
properties, null, new List<InputModelType>(), null, null, new Dictionary<string, InputModelType>(), null, modelAsStruct: true);
@ -107,12 +86,9 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
_ => throw new ArgumentException("Unsupported input type.")
};
private void MockPluginSetValue(List<InputModelProperty> properties)
private Func<InputType, CSharpType> MockPluginSetValue(List<InputModelProperty> properties)
{
var mockPluginInstance = new Mock<CodeModelPlugin>(_generatorContext) { };
var mockTypeFactory = new Mock<TypeFactory>() { };
mockTypeFactory.Protected().Setup<CSharpType>("CreateCSharpTypeCore", ItExpr.IsAny<InputType>()).Returns((InputType inputType) =>
return (InputType inputType) =>
{
// Lookup the inputType in the list and return the corresponding CSharpType
var inputModelProperty = properties.Where(prop => prop.Type.Name == inputType.Name).FirstOrDefault();
@ -124,10 +100,7 @@ namespace Microsoft.Generator.CSharp.Tests.Writers
{
throw new ArgumentException("Unsupported input type.");
}
});
mockPluginInstance.SetupGet(p => p.TypeFactory).Returns(mockTypeFactory.Object);
_mockPlugin?.SetValue(null, mockPluginInstance.Object);
};
}
// common usages definitions