diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/AutofixtureServiceProviderAttribute.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/AutofixtureServiceProviderAttribute.cs deleted file mode 100644 index bee3715cb..000000000 --- a/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/AutofixtureServiceProviderAttribute.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Reflection; -using AutoFixture; -using AutoFixture.Kernel; -using AutoFixture.Xunit2; -using Elsa.Testing.Shared.AutoFixture.SpecimenBuilders; - -namespace Elsa.Testing.Shared.AutoFixture.Attributes -{ - /// - /// Customizes the parameter so that it creates an - /// using Moq. That mock service provider gets services by resolving them from Autofixture. - /// - /// - public class AutofixtureServiceProviderAttribute : CustomizeAttribute - { - public override ICustomization GetCustomization(ParameterInfo parameter) - => new AutofixtureServiceProviderCustomization(parameter); - - class AutofixtureServiceProviderCustomization : ICustomization - { - readonly ParameterInfo parameter; - - public void Customize(IFixture fixture) - { - fixture.Customizations.Insert(0, GetSpecimenBuilder()); - } - - ISpecimenBuilder GetSpecimenBuilder() - { - var paramSpec = new ParameterSpecification(parameter.ParameterType, parameter.Name); - var specimenBuilder = new AutofixtureServiceProviderSpecimenBuilder(); - return new FilteringSpecimenBuilder(specimenBuilder, paramSpec); - } - - public AutofixtureServiceProviderCustomization(ParameterInfo parameter) - { - this.parameter = parameter; - } - } - - } -} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/ElsaHostBuilderBuilderCustomizeAttributeBase.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/ElsaHostBuilderBuilderCustomizeAttributeBase.cs index 4d6ca511f..0a2f044da 100644 --- a/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/ElsaHostBuilderBuilderCustomizeAttributeBase.cs +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/ElsaHostBuilderBuilderCustomizeAttributeBase.cs @@ -36,7 +36,7 @@ namespace Elsa.Testing.Shared.AutoFixture.Attributes public ISpecimenBuilderNode Transform(ISpecimenBuilder builder) { - return new Postprocessor(builder, new ElsaHostBuilderBuilderCommand(builderCustomizer), new IsAnElsaHostBuilderBuilderSpec()); + return new Postprocessor(builder, new ElsaHostBuilderBuilderCommand(builderCustomizer), IsInstanceOf.Type()); } public ElsaHostBuilderBuilderTransformation(Action builderCustomizer) diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/WithAutofixtureResolutionAttribute.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/WithAutofixtureResolutionAttribute.cs new file mode 100644 index 000000000..d74f72ea4 --- /dev/null +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/Attributes/WithAutofixtureResolutionAttribute.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; +using AutoFixture; +using AutoFixture.Xunit2; +using Elsa.Testing.Shared.AutoFixture.Behaviors; +using Elsa.Testing.Shared.AutoFixture.SpecimenBuilders; +using Moq; + +namespace Elsa.Testing.Shared.AutoFixture.Attributes +{ + /// + /// Customizes the parameter so that the + /// created by Moq will resolve services of the appropriate type, creating + /// them using Autofixture. + /// + /// + public class WithAutofixtureResolutionAttribute : CustomizeAttribute + { + public override ICustomization GetCustomization(ParameterInfo parameter) + => new AutofixtureServiceProviderCustomization(); + + class AutofixtureServiceProviderCustomization : ICustomization + { + public void Customize(IFixture fixture) + { + var behavior = BehaviorFactory.GetPostprocessingBehavior(AutofixtureResolutionServiceProviderSpecimenBuilder.AddAutofixtureResolution); + fixture.Behaviors.Add(behavior); + } + } + + } +} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/Behaviors/BehaviorFactory.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/Behaviors/BehaviorFactory.cs new file mode 100644 index 000000000..0815be4f0 --- /dev/null +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/Behaviors/BehaviorFactory.cs @@ -0,0 +1,49 @@ +using System; +using AutoFixture.Kernel; +using Elsa.Testing.Shared.AutoFixture.Specifications; + +namespace Elsa.Testing.Shared.AutoFixture.Behaviors +{ + public class BehaviorFactory + { + public static ISpecimenBuilderTransformation GetPostprocessingBehavior(Action postProcessingAction) where T : class + => new PostprocessingTransformation(postProcessingAction); + + public static ISpecimenBuilderTransformation GetPostprocessingBehavior(Action postProcessingAction) where T : class + => new PostprocessingTransformation((speciman, ctx) => postProcessingAction(speciman)); + + class PostprocessingTransformation : ISpecimenBuilderTransformation where T : class + { + readonly Action builderCustomizer; + + public ISpecimenBuilderNode Transform(ISpecimenBuilder builder) + { + var command = new PostprocessingCommand(builderCustomizer); + var spec = IsInstanceOf.Type(); + + return new Postprocessor(builder, command, spec); + } + + public PostprocessingTransformation(Action builderCustomizer) + { + this.builderCustomizer = builderCustomizer ?? throw new ArgumentNullException(nameof(builderCustomizer)); + } + } + + class PostprocessingCommand : ISpecimenCommand where T : class + { + readonly Action builderCustomizer; + + public void Execute(object specimen, ISpecimenContext context) + { + var builder = (T) specimen; + builderCustomizer(builder, context); + } + + public PostprocessingCommand(Action builderCustomizer) + { + this.builderCustomizer = builderCustomizer ?? throw new ArgumentNullException(nameof(builderCustomizer)); + } + } + } +} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/Specifications/IsAnElsaHostBuilderBuilderSpec.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/Specifications/IsAnElsaHostBuilderBuilderSpec.cs deleted file mode 100644 index dada67a6b..000000000 --- a/test/shared/Elsa.Testing.Shared/AutoFixture/Specifications/IsAnElsaHostBuilderBuilderSpec.cs +++ /dev/null @@ -1,10 +0,0 @@ -using AutoFixture.Kernel; -using Elsa.Testing.Shared.Helpers; - -namespace Elsa.Testing.Shared.AutoFixture.Specifications -{ - public class IsAnElsaHostBuilderBuilderSpec : IRequestSpecification - { - public bool IsSatisfiedBy(object request) => request is ElsaHostBuilderBuilder; - } -} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/Specifications/IsInstanceOf.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/Specifications/IsInstanceOf.cs new file mode 100644 index 000000000..025469dae --- /dev/null +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/Specifications/IsInstanceOf.cs @@ -0,0 +1,20 @@ +using System; +using AutoFixture.Kernel; +using Elsa.Testing.Shared.AutoFixture.SpecimenBuilders; + +namespace Elsa.Testing.Shared.AutoFixture.Specifications +{ + public class IsInstanceOf : IRequestSpecification + { + readonly Type type; + + public bool IsSatisfiedBy(object request) => request.IsAnAutofixtureRequestForType(type); + + public IsInstanceOf(Type type) + { + this.type = type ?? throw new ArgumentNullException(nameof(type)); + } + + public static IsInstanceOf Type() => new IsInstanceOf(typeof(T)); + } +} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/AutofixtureResolutionServiceProviderSpecimenBuilder.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/AutofixtureResolutionServiceProviderSpecimenBuilder.cs new file mode 100644 index 000000000..e5c9469b3 --- /dev/null +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/AutofixtureResolutionServiceProviderSpecimenBuilder.cs @@ -0,0 +1,30 @@ +using System; +using AutoFixture.Kernel; +using Moq; + +namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders +{ + public class AutofixtureResolutionServiceProviderSpecimenBuilder : ISpecimenBuilder + { + public object Create(object request, ISpecimenContext context) + { + if(!request.IsAnAutofixtureRequestForType()) + return new NoSpecimen(); + + var provider = Mock.Of(); + AddAutofixtureResolution(provider, context); + return provider; + } + + public static void AddAutofixtureResolution(IServiceProvider provider, ISpecimenContext context) + { + var mock = Mock.Get(provider); + + mock.Name = $"Autofixture_{nameof(IServiceProvider)}-{Guid.NewGuid()}"; + mock + .Setup(x => x.GetService(It.IsAny())) + .Returns((Type t) => context.Resolve(t)); + + } + } +} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/AutofixtureServiceProviderSpecimenBuilder.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/AutofixtureServiceProviderSpecimenBuilder.cs deleted file mode 100644 index 26a332af3..000000000 --- a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/AutofixtureServiceProviderSpecimenBuilder.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using AutoFixture.Kernel; -using Moq; - -namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders -{ - /// - /// Creates a mock which gets services - /// by resolving them from Autofixture. - /// - public class AutofixtureServiceProviderSpecimenBuilder : ISpecimenBuilder - { - public object Create(object request, ISpecimenContext context) - { - if(request.IsAnAutofixtureRequestForType()) - return GetServiceProvider(context); - - return new NoSpecimen(); - } - - static object GetServiceProvider(ISpecimenContext context) - { - var provider = new Mock(); - - provider.Name = $"Autofixture_{nameof(IServiceProvider)}-{Guid.NewGuid()}"; - provider - .Setup(x => x.GetService(It.IsAny())) - .Returns((Type t) => context.Resolve(t)); - - return provider.Object; - } - } -} \ No newline at end of file diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/RequestExtensions.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/RequestExtensions.cs index ab8427d75..e3c0226d1 100644 --- a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/RequestExtensions.cs +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/RequestExtensions.cs @@ -1,3 +1,4 @@ +using System; using System.Reflection; namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders @@ -15,12 +16,21 @@ namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders /// The request object /// The desired specimen type /// true if the is a request for an instance of ; false otherwise. - public static bool IsAnAutofixtureRequestForType(this object request) + public static bool IsAnAutofixtureRequestForType(this object request) => request.IsAnAutofixtureRequestForType(typeof(T)); + + /// + /// Gets a value which indicates if the specified qualifies as an Autofixture + /// request for an instance of the specified generic type. + /// + /// The request object + /// The desired specimen type + /// true if the is a request for an instance of ; false otherwise. + public static bool IsAnAutofixtureRequestForType(this object request, Type type) { - if(Equals(request, typeof(T))) + if(Equals(request, type)) return true; - if(request is ParameterInfo paramInfo && paramInfo.ParameterType == typeof(T)) + if(request is ParameterInfo paramInfo && paramInfo.ParameterType == type) return true; return false; diff --git a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/StubActivityExecutionContextSpecimenBuilder.cs b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/StubActivityExecutionContextSpecimenBuilder.cs index a17fc5b11..260fa147f 100644 --- a/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/StubActivityExecutionContextSpecimenBuilder.cs +++ b/test/shared/Elsa.Testing.Shared/AutoFixture/SpecimenBuilders/StubActivityExecutionContextSpecimenBuilder.cs @@ -25,7 +25,7 @@ namespace Elsa.Testing.Shared.AutoFixture.SpecimenBuilders } static IServiceProvider GetServiceProvider(ISpecimenContext context) - => (IServiceProvider) new AutofixtureServiceProviderSpecimenBuilder().Create(typeof(IServiceProvider), context); + => (IServiceProvider) new AutofixtureResolutionServiceProviderSpecimenBuilder().Create(typeof(IServiceProvider), context); static WorkflowExecutionContext GetWorkflowExecutionContext(ISpecimenContext context, IServiceProvider serviceProvider) => new WorkflowExecutionContext(serviceProvider, Mock.Of(), new WorkflowInstance()); diff --git a/test/shared/Elsa.Testing.Shared/Helpers/TemporaryFolder.cs b/test/shared/Elsa.Testing.Shared/Helpers/TemporaryFolder.cs index 9bf48bd8e..425dbd4e6 100644 --- a/test/shared/Elsa.Testing.Shared/Helpers/TemporaryFolder.cs +++ b/test/shared/Elsa.Testing.Shared/Helpers/TemporaryFolder.cs @@ -20,7 +20,11 @@ namespace Elsa.Testing.Shared.Helpers /// /// The relative path, within the temporary folder. /// A path for content within the temporary folder. - public string GetContainedPath(string relativePath) => Path.Combine(Folder, relativePath); + public string GetContainedPath(string relativePath) + { + Directory.CreateDirectory(Folder); + return Path.Combine(Folder, relativePath); + } public void Dispose() { diff --git a/test/unit/Elsa.UnitTests/Services/ActivityExecutionContextForActivityBlueprintFactoryTests.cs b/test/unit/Elsa.UnitTests/Services/ActivityExecutionContextForActivityBlueprintFactoryTests.cs index 8949c53a0..32e6479dd 100644 --- a/test/unit/Elsa.UnitTests/Services/ActivityExecutionContextForActivityBlueprintFactoryTests.cs +++ b/test/unit/Elsa.UnitTests/Services/ActivityExecutionContextForActivityBlueprintFactoryTests.cs @@ -9,7 +9,7 @@ namespace Elsa.Services public class ActivityExecutionContextForActivityBlueprintFactoryTests { [Theory(DisplayName = "The CreateActivityExecutionContext method should create a context using the activity blueprint, the workflow execution context, cancellation token and injected service provider."), AutoMoqData] - public void CreateActivityExecutionContextCreatesContextUsingBlueprintExecutionContextCancellationTokenAndServiceProvider([AutofixtureServiceProvider] IServiceProvider serviceProvider, + public void CreateActivityExecutionContextCreatesContextUsingBlueprintExecutionContextCancellationTokenAndServiceProvider([WithAutofixtureResolution] IServiceProvider serviceProvider, IActivityBlueprint activityBlueprint, [OmitOnRecursion] WorkflowExecutionContext workflowExecutionContext, CancellationToken cancellationToken) diff --git a/test/unit/Elsa.UnitTests/Services/Models/ActivityExecutionContextTests.cs b/test/unit/Elsa.UnitTests/Services/Models/ActivityExecutionContextTests.cs index 18c9455ce..ba8e68ce5 100644 --- a/test/unit/Elsa.UnitTests/Services/Models/ActivityExecutionContextTests.cs +++ b/test/unit/Elsa.UnitTests/Services/Models/ActivityExecutionContextTests.cs @@ -8,7 +8,7 @@ namespace Elsa.Services.Models public class ActivityExecutionContextTests { [Theory(DisplayName = "The PurgeVariables method should clear the Variables instance associated with the WorkflowInstance associated with the Workflow Execution Context"), AutoMoqData] - public void PurgeVariables_clears_workflow_execution_context_workflow_instance_variables([AutofixtureServiceProvider, Frozen] IServiceProvider serviceProvider, + public void PurgeVariables_clears_workflow_execution_context_workflow_instance_variables([WithAutofixtureResolution, Frozen] IServiceProvider serviceProvider, [OmitOnRecursion,NoAutoProperties] ActivityExecutionContext sut, string variableName, object variableValue) diff --git a/test/unit/Elsa.UnitTests/Services/Models/WorkflowExecutionContextTests.cs b/test/unit/Elsa.UnitTests/Services/Models/WorkflowExecutionContextTests.cs index 160ff796b..712705324 100644 --- a/test/unit/Elsa.UnitTests/Services/Models/WorkflowExecutionContextTests.cs +++ b/test/unit/Elsa.UnitTests/Services/Models/WorkflowExecutionContextTests.cs @@ -8,7 +8,7 @@ namespace Elsa.Services.Models public class WorkflowExecutionContextTests { [Theory(DisplayName = "The PurgeVariables method should clear the Variables instance associated with the WorkflowInstance"), AutoMoqData] - public void PurgeVariables_clears_workflow_execution_context_workflow_instance_variables([AutofixtureServiceProvider, Frozen] IServiceProvider serviceProvider, + public void PurgeVariables_clears_workflow_execution_context_workflow_instance_variables([WithAutofixtureResolution, Frozen] IServiceProvider serviceProvider, [OmitOnRecursion,NoAutoProperties] WorkflowExecutionContext sut, string variableName, object variableValue) diff --git a/test/unit/Elsa.UnitTests/Services/WorkflowBuilderTests.cs b/test/unit/Elsa.UnitTests/Services/WorkflowBuilderTests.cs index e38ec7990..9002f53d0 100644 --- a/test/unit/Elsa.UnitTests/Services/WorkflowBuilderTests.cs +++ b/test/unit/Elsa.UnitTests/Services/WorkflowBuilderTests.cs @@ -10,7 +10,7 @@ namespace Elsa.Services public class WorkflowBuilderTests { [Theory(DisplayName = "The Build method should return a workflow blueprint with the WorkflowBurst persistence behaviour if no behaviour was specified"), AutoMoqData] - public void BuildShouldReturnWorkflowBlueprintWithWorkflowBurstPersistenceBehaviourIfNoBehaviourSpecified([AutofixtureServiceProvider, Frozen] IServiceProvider serviceProvider, + public void BuildShouldReturnWorkflowBlueprintWithWorkflowBurstPersistenceBehaviourIfNoBehaviourSpecified([WithAutofixtureResolution, Frozen] IServiceProvider serviceProvider, WorkflowBuilder sut, string idPrefix) { diff --git a/test/unit/Elsa.UnitTests/Services/WorkflowExecutionContextForWorkflowBlueprintFactoryTests.cs b/test/unit/Elsa.UnitTests/Services/WorkflowExecutionContextForWorkflowBlueprintFactoryTests.cs index 20ba00b63..55ac4a4b4 100644 --- a/test/unit/Elsa.UnitTests/Services/WorkflowExecutionContextForWorkflowBlueprintFactoryTests.cs +++ b/test/unit/Elsa.UnitTests/Services/WorkflowExecutionContextForWorkflowBlueprintFactoryTests.cs @@ -11,7 +11,7 @@ namespace Elsa.Services public class WorkflowExecutionContextForWorkflowBlueprintFactoryTests { [Theory(DisplayName = "The CreateWorkflowExecutionContextAsync method returns an execution context using the blueprint, an instance and the service provider"), AutoMoqData] - public async Task CreateWorkflowExecutionContextAsyncReturnsContextWithBlueprintInstanceAndServiceProvider([AutofixtureServiceProvider] IServiceProvider serviceProvider, + public async Task CreateWorkflowExecutionContextAsyncReturnsContextWithBlueprintInstanceAndServiceProvider([WithAutofixtureResolution] IServiceProvider serviceProvider, IWorkflowFactory workflowFactory, IWorkflowBlueprint workflowBlueprint, [OmitOnRecursion] WorkflowInstance instance) diff --git a/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs b/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs index 4ed32364e..c2406979b 100644 --- a/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs +++ b/test/unit/Elsa.UnitTests/Triggers/TriggersForBlueprintsProviderTests.cs @@ -38,7 +38,7 @@ namespace Elsa.UnitTests.Triggers WorkflowTrigger trigger4, WorkflowTrigger trigger5, WorkflowTrigger trigger6, - [AutofixtureServiceProvider] IServiceProvider serviceProvider, + [WithAutofixtureResolution] IServiceProvider serviceProvider, [NoAutoProperties] WorkflowInstance workflowInstance) { Mock.Get(activityTypeService)