diff --git a/src/modules/Elsa.Workflows.Core/Activities/SetVariable.cs b/src/modules/Elsa.Workflows.Core/Activities/SetVariable.cs
index a12b35086..ba99e893d 100644
--- a/src/modules/Elsa.Workflows.Core/Activities/SetVariable.cs
+++ b/src/modules/Elsa.Workflows.Core/Activities/SetVariable.cs
@@ -89,7 +89,7 @@ public class SetVariable : CodeActivity
/// The variable to assign the value to.
///
[Input(Description = "The variable to assign the value to.")]
- public Variable Variable { get; set; } = null!;
+ public Variable? Variable { get; set; }
///
/// The value to assign.
@@ -101,9 +101,13 @@ public class SetVariable : CodeActivity
protected override void Execute(ActivityExecutionContext context)
{
// Always refer to the variable by ID to ensure that the variable is resolved from the correct scope.
- var variableId = Variable.Id;
+ var variableId = Variable?.Id;
var variable = context.ExpressionExecutionContext.EnumerateVariablesInScope().FirstOrDefault(x => x.Id == variableId);
+
+ if (variable == null)
+ throw new($"Variable '{variableId}' not found.");
+
var value = context.Get(Value);
- variable?.Set(context, value);
+ variable.Set(context, value);
}
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs b/src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs
index 282d07be3..f5b4482ca 100644
--- a/src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs
+++ b/src/modules/Elsa.Workflows.Core/Services/ActivityRegistry.cs
@@ -57,7 +57,6 @@ public class ActivityRegistry(IActivityDescriber activityDescriber, IEnumerable<
var activityDescriptor = await activityDescriber.DescribeActivityAsync(activityType, cancellationToken);
-
Add(activityDescriptor, _activityDescriptors, _manualActivityDescriptors);
_manualActivityDescriptors.Add(activityDescriptor);
}
diff --git a/test/unit/Elsa.Activities.UnitTests/Helpers/ActivityTestHelper.cs b/test/unit/Elsa.Activities.UnitTests/Helpers/ActivityTestHelper.cs
index 9b01d48f0..1a2adedb4 100644
--- a/test/unit/Elsa.Activities.UnitTests/Helpers/ActivityTestHelper.cs
+++ b/test/unit/Elsa.Activities.UnitTests/Helpers/ActivityTestHelper.cs
@@ -7,6 +7,7 @@ using Elsa.Workflows;
using Elsa.Workflows.CommitStates;
using Elsa.Workflows.Management.Providers;
using Elsa.Workflows.Management.Services;
+using Elsa.Workflows.PortResolvers;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
@@ -26,16 +27,15 @@ public static class ActivityTestHelper
///
/// The activity to execute
/// The ActivityExecutionContext used for execution
- public static async Task ExecuteActivityAsync(IActivity activity)
+ public static async Task ExecuteActivityAsync(IActivity activity, Action? configureServices = null)
{
- var context = CreateMinimalActivityExecutionContext(activity, out var serviceProvider);
-
+ var context = await CreateMinimalActivityExecutionContext(activity, configureServices);
+
// Set up variables and inputs, then execute the activity
await SetupExistingVariablesAsync(activity, context);
- await SetupInputValuesInMemoryAsync(activity, context, serviceProvider);
await context.EvaluateInputPropertiesAsync();
await activity.ExecuteAsync(context);
-
+
return context;
}
@@ -44,82 +44,61 @@ public static class ActivityTestHelper
/// This helper method creates a real WorkflowExecutionContext using the minimal workflow pattern
/// to provide proper context for activities.
///
- private static ActivityExecutionContext CreateMinimalActivityExecutionContext(IActivity activity, out IServiceProvider serviceProvider)
+ private static async Task CreateMinimalActivityExecutionContext(IActivity activity, Action? configureServices)
{
// Create a minimal service provider with the required services for expression evaluation
var services = new ServiceCollection();
-
+
// Add core services
+ services.AddLogging();
services.AddSingleton(_ => Substitute.For());
services.AddSingleton(_ => Substitute.For());
services.AddSingleton();
-
- // Add real expression evaluation services instead of mocks
services.AddScoped();
-
- // Add the well-known type registry required by expression handlers
services.AddSingleton();
-
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
+ services.AddScoped();
+
// Add the default expression descriptor provider which includes Literal expressions
services.AddSingleton();
services.AddSingleton();
-
+
services.AddSingleton(_ => Substitute.For());
-
- // Mock the complex workflow-level dependencies
- services.AddSingleton(_ => Substitute.For());
-
- // Set up the activity registry lookup service to return proper descriptors
- var activityRegistryLookup = Substitute.For();
- activityRegistryLookup.FindAsync(Arg.Any(), Arg.Any()).Returns(callInfo =>
- {
- var activityType = callInfo.ArgAt(0);
- return Task.FromResult(new ActivityDescriptor
- {
- TypeName = activityType,
- Kind = ActivityKind.Action,
- Category = "Test",
- Description = "Test activity for unit testing",
- Version = 1
- });
- });
-
- services.AddSingleton(_ => activityRegistryLookup);
-
- services.AddSingleton(_ => Substitute.For());
- services.AddSingleton(_ => Substitute.For());
+
services.AddSingleton(_ => Substitute.For());
services.AddSingleton(_ => Substitute.For());
services.AddSingleton(_ => Substitute.For());
- serviceProvider = services.BuildServiceProvider();
-
- // Create a minimal workflow
- activity.Id ??= $"test-activity-{Guid.NewGuid()}";
-
- var workflow = new Workflow
- {
- Root = activity
- };
-
- // Create a simple workflow graph manually instead of using the builder
- var rootNode = new ActivityNode(activity, "Root");
- var nodes = new List { rootNode };
- var workflowGraph = new WorkflowGraph(workflow, rootNode, nodes);
-
+ // Call the configure services action if provided.
+ configureServices?.Invoke(services);
+
+ var serviceProvider = services.BuildServiceProvider();
+ var activityRegistry = serviceProvider.GetRequiredService();
+ var workflowGraphBuilder = serviceProvider.GetRequiredService();
+ await activityRegistry.RegisterAsync(activity.GetType());
+ var workflow = Workflow.FromActivity(activity);
+ var workflowGraph = await workflowGraphBuilder.BuildAsync(workflow);
+
// Create workflow execution context using the static factory method
- var workflowExecutionContext = WorkflowExecutionContext.CreateAsync(
- serviceProvider,
- workflowGraph,
- $"test-instance-{Guid.NewGuid()}",
+ var workflowExecutionContext = await WorkflowExecutionContext.CreateAsync(
+ serviceProvider,
+ workflowGraph,
+ $"test-instance-{Guid.NewGuid()}",
CancellationToken.None
- ).GetAwaiter().GetResult();
-
+ );
+
// Create ActivityExecutionContext for the actual activity we want to test
- var activityExecutionContext = workflowExecutionContext.CreateActivityExecutionContextAsync(activity)
- .GetAwaiter().GetResult();
-
- return activityExecutionContext;
+ return await workflowExecutionContext.CreateActivityExecutionContextAsync(activity);
}
///
@@ -133,7 +112,7 @@ public static class ActivityTestHelper
.Where(p => p.PropertyType.IsGenericType &&
p.PropertyType.BaseType == typeof(Variable))
.ToList();
-
+
foreach (var variable in variableProperties.Select(property => (Variable)property.GetValue(activity)!))
{
variable.Set(context.ExpressionExecutionContext, variable.Value);
@@ -141,35 +120,4 @@ public static class ActivityTestHelper
return Task.CompletedTask;
}
-
- ///
- /// Sets up input values in memory blocks so that context.Get() can find them during activity execution.
- /// This mimics what the workflow engine does when evaluating inputs.
- ///
- private static async Task SetupInputValuesInMemoryAsync(IActivity activity, ActivityExecutionContext context, IServiceProvider serviceProvider)
- {
- var activityType = activity.GetType();
- var inputProperties = activityType.GetProperties()
- .Where(p => p.PropertyType.IsGenericType &&
- p.PropertyType.GetGenericTypeDefinition() == typeof(Input<>))
- .ToList();
-
- foreach (var input in inputProperties.Select(property => property.GetValue(activity) as Input))
- {
- if (input?.Expression == null)
- {
- continue;
- }
-
- // Get the memory block reference for this input
- var memoryBlockReference = input.MemoryBlockReference();
-
- // Evaluate the input using the expression evaluator
- var expressionEvaluator = serviceProvider.GetService();
- var evaluatedValue = await expressionEvaluator!.EvaluateAsync(input, context.ExpressionExecutionContext);
-
- // Set the value in the memory block
- memoryBlockReference.Set(context, evaluatedValue);
- }
- }
-}
+}
\ No newline at end of file
diff --git a/test/unit/Elsa.Activities.UnitTests/Primitives/SetVariableTests.cs b/test/unit/Elsa.Activities.UnitTests/Primitives/SetVariableTests.cs
index f94ba1812..15d7bf0d8 100644
--- a/test/unit/Elsa.Activities.UnitTests/Primitives/SetVariableTests.cs
+++ b/test/unit/Elsa.Activities.UnitTests/Primitives/SetVariableTests.cs
@@ -1,455 +1,49 @@
using Elsa.Activities.UnitTests.Helpers;
-using Elsa.Workflows;
-using Elsa.Expressions.Models;
-using System.Text.Json;
namespace Elsa.Activities.UnitTests.Primitives;
public class SetVariableTests
{
[Fact]
- public async Task Should_Set_Variable_Integer()
+ public async Task Should_Set_Variable_Integer()
{
// Arrange
+ const int expected = 42; // The answer to life, the universe and everything.
var variable = new Variable("myVar", 0, "myVar");
- var setVariable = new SetVariable(variable, new Input(42, "inputId"));
-
+ var setVariable = new SetVariable(variable, new Input(expected));
+
// Act
var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
+
// Assert
var result = variable.Get(context);
- Assert.Equal(42, result);
+ Assert.Equal(expected, result);
}
[Fact]
- public async Task Should_Set_Variable_String()
+ public async Task Should_Not_Throw_When_Variable_Is_Null()
{
// Arrange
- var variable = new Variable("myStringVar", "", "myStringVar");
- var setVariable = new SetVariable(variable, new Input("Hello World", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("Hello World", result);
+ var setVariable = new SetVariable(null!, new Input("test value"));
+
+ // Act & Assert
+ var exception = await Record.ExceptionAsync(async () => await ActivityTestHelper.ExecuteActivityAsync(setVariable));
+
+ Assert.NotNull(exception);
}
[Fact]
- public async Task Should_Overwrite_Existing_Variable()
+ public async Task Should_Set_Variable_To_Null_Value()
{
// Arrange
- var variable = new Variable("existingVar", 100, "inputId");
- var setVariable = new SetVariable(variable, new Input(200, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert - verify the original value was overwritten
- var result = variable.Get(context);
- Assert.Equal(200, result);
- }
+ var variable = new Variable("myVar", "initial value", "myVar");
+ var setVariable = new SetVariable(variable, new Input(default(string)));
- [Fact]
- public async Task Should_Assign_Null_Value()
- {
- // Arrange
- var variable = new Variable("nullVar", "initial", "nullVar");
- var setVariable = new SetVariable(variable, new Input((string)null!, "inputId"));
-
// Act
var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
+
// Assert
var result = variable.Get(context);
Assert.Null(result);
}
-
- [Fact]
- public async Task Should_Set_Variable_With_Special_Characters()
- {
- // Arrange
- var variable = new Variable("special_var-123", "", "specialVar");
- const string specialValue = "Special chars: !@#$%^&*()_+-=[]{}|;':\",./<>?";
- var setVariable = new SetVariable(variable, new Input(specialValue, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal(specialValue, result);
- }
-
- [Fact]
- public async Task Should_Serialize_Complex_Object()
- {
- // Arrange
- var complexObject = new ComplexTestObject
- {
- Id = 123,
- Name = "Test Object",
- Properties = new Dictionary
- {
- {"prop1", "value1"},
- {"prop2", 456},
- {"prop3", true}
- },
- Items = ["item1", "item2", "item3"]
- };
-
- var variable = new Variable("complexVar", null!, "complexVar");
- var setVariable = new SetVariable(variable, new Input(complexObject, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.NotNull(result);
- Assert.Equal(complexObject.Id, result.Id);
- Assert.Equal(complexObject.Name, result.Name);
- Assert.Equal(complexObject.Properties.Count, result.Properties.Count);
- Assert.Equal(complexObject.Items.Length, result.Items.Length);
- }
-
- [Fact]
- public async Task Should_Assign_Large_Payload()
- {
- // Arrange
- var largePayload = new string('A', 1024 * 1024);
- var variable = new Variable("largeVar", "", "largeVar");
- var setVariable = new SetVariable(variable, new Input(largePayload, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal(largePayload.Length, result.Length);
- Assert.Equal(largePayload, result);
- }
-
- [Fact]
- public async Task Should_Handle_Case_Sensitivity_On_Variable_Names()
- {
- // Arrange
- var variable1 = new Variable("CaseSensitive", "value1", "var1");
- var variable2 = new Variable("casesensitive", "value2", "var2");
-
- var setVariable1 = new SetVariable(variable1, new Input("updated1", "input1"));
- var setVariable2 = new SetVariable(variable2, new Input("updated2", "input2"));
-
- // Act
- var context1 = await ActivityTestHelper.ExecuteActivityAsync(setVariable1);
- var context2 = await ActivityTestHelper.ExecuteActivityAsync(setVariable2);
-
- // Assert - Variables with different casing should be treated as separate
- var result1 = variable1.Get(context1);
- var result2 = variable2.Get(context2);
-
- Assert.Equal("updated1", result1);
- Assert.Equal("updated2", result2);
- }
-
- [Fact]
- public async Task Should_Reassign_Variable_Multiple_Times()
- {
- // Arrange
- var variable = new Variable("multiVar", 0, "multiVar");
-
- // Act - Multiple assignments
- var setVariable1 = new SetVariable(variable, new Input(10, "input1"));
- var context1 = await ActivityTestHelper.ExecuteActivityAsync(setVariable1);
- var result1 = variable.Get(context1);
-
- var setVariable2 = new SetVariable(variable, new Input(20, "input2"));
- var context2 = await ActivityTestHelper.ExecuteActivityAsync(setVariable2);
- var result2 = variable.Get(context2);
-
- var setVariable3 = new SetVariable(variable, new Input(30, "input3"));
- var context3 = await ActivityTestHelper.ExecuteActivityAsync(setVariable3);
- var result3 = variable.Get(context3);
-
- // Assert - Each execution should update the variable
- Assert.Equal(10, result1);
- Assert.Equal(20, result2);
- Assert.Equal(30, result3);
- }
-
- [Fact]
- public async Task Should_Handle_Boolean_Values()
- {
- // Arrange
- var variable = new Variable("boolVar", false, "boolVar");
- var setVariable = new SetVariable(variable, new Input(true, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.True(result);
- }
-
- [Fact]
- public async Task Should_Handle_DateTime_Values()
- {
- // Arrange
- var testDate = new DateTime(2025, 10, 8, 14, 30, 0);
- var variable = new Variable("dateVar", DateTime.MinValue, "dateVar");
- var setVariable = new SetVariable(variable, new Input(testDate, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal(testDate, result);
- }
-
- [Fact]
- public async Task Should_Handle_Decimal_Values()
- {
- // Arrange
- var decimalValue = 123.456789m;
- var variable = new Variable("decimalVar", 0m, "decimalVar");
- var setVariable = new SetVariable(variable, new Input(decimalValue, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal(decimalValue, result);
- }
-
- [Fact]
- public async Task Should_Handle_Array_Values()
- {
- // Arrange
- var arrayValue = new[] { "item1", "item2", "item3" };
- var variable = new Variable("arrayVar", null!, "arrayVar");
- var setVariable = new SetVariable(variable, new Input(arrayValue, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.NotNull(result);
- Assert.Equal(arrayValue.Length, result.Length);
- Assert.Equal(arrayValue, result);
- }
-
- [Fact]
- public async Task Should_Handle_Dictionary_Values()
- {
- // Arrange
- var dictionaryValue = new Dictionary
- {
- {"key1", "value1"},
- {"key2", 123},
- {"key3", true}
- };
- var variable = new Variable>("dictVar", null!, "dictVar");
- var setVariable = new SetVariable>(variable, new Input>(dictionaryValue, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.NotNull(result);
- Assert.Equal(dictionaryValue.Count, result.Count);
- Assert.Equal(dictionaryValue["key1"], result["key1"]);
- Assert.Equal(dictionaryValue["key2"], result["key2"]);
- Assert.Equal(dictionaryValue["key3"], result["key3"]);
- }
-
- [Fact]
- public async Task Should_Evaluate_Variable_Name_Via_Expression()
- {
- // Arrange - Use an expression for the variable name
- var dynamicVariableName = "dynamic_var_" + DateTime.Now.Ticks;
- var variable = new Variable(dynamicVariableName, "", "dynamicVar");
- var setVariable = new SetVariable(variable, new Input("Dynamic Value", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("Dynamic Value", result);
- Assert.Equal(dynamicVariableName, variable.Name);
- }
-
- [Fact]
- public async Task Should_Evaluate_Value_Via_Expression()
- {
- // Arrange - Use a computed expression for the value
- var computedValue = $"Computed at {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
- var variable = new Variable("expressionVar", "", "expressionVar");
- var setVariable = new SetVariable(variable, new Input(computedValue, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal(computedValue, result);
- Assert.Contains("Computed at", result);
- }
-
- [Fact]
- public async Task Should_Handle_Expression_That_Returns_Null()
- {
- // Arrange - Expression that evaluates to null
- var variable = new Variable("nullExpressionVar", "initial", "nullExpressionVar");
- var setVariable = new SetVariable(variable, new Input((string)null!, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Null(result);
- }
-
- [Fact]
- public async Task Should_Handle_Undefined_Expression_Result()
- {
- // Arrange - Test handling of undefined/default values
- var variable = new Variable("undefinedVar", null, "undefinedVar");
- var setVariable = new SetVariable(variable, new Input((int?)null, "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Null(result);
- }
-
- [Fact]
- public async Task Should_Handle_Zero_Length_Variable_Name()
- {
- // Arrange
- var variable = new Variable(string.Empty, "test", "emptyNameVar");
- var setVariable = new SetVariable(variable, new Input("value", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("value", result);
- }
-
- [Fact]
- public async Task Should_Handle_Unicode_Variable_Names()
- {
- // Arrange - Test with Unicode characters in variable names
- var unicodeVariableName = "变量名_متغیر_переменная_🚀";
- var variable = new Variable(unicodeVariableName, "", "unicodeVar");
- var setVariable = new SetVariable(variable, new Input("Unicode Value", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("Unicode Value", result);
- Assert.Equal(unicodeVariableName, variable.Name);
- }
-
- [Fact]
- public async Task Should_Handle_Extremely_Long_Variable_Name()
- {
- // Arrange - Test with very long variable name
- var longVariableName = new string('a', 1000);
- var variable = new Variable(longVariableName, "", "longNameVar");
- var setVariable = new SetVariable(variable, new Input("Long Name Value", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("Long Name Value", result);
- Assert.Equal(1000, variable.Name.Length);
- }
-
- [Fact]
- public async Task Should_Handle_Numeric_Variable_Names()
- {
- // Arrange - Test with numeric variable names
- var numericVariableName = "12345";
- var variable = new Variable(numericVariableName, "", "numericVar");
- var setVariable = new SetVariable(variable, new Input("Numeric Name Value", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("Numeric Name Value", result);
- Assert.Equal(numericVariableName, variable.Name);
- }
-
- [Fact]
- public async Task Should_Handle_Variable_Name_With_Spaces()
- {
- // Arrange - Test with spaces in variable names
- var spacedVariableName = "variable with spaces";
- var variable = new Variable(spacedVariableName, "", "spacedVar");
- var setVariable = new SetVariable(variable, new Input("Spaced Name Value", "inputId"));
-
- // Act
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
-
- // Assert
- var result = variable.Get(context);
- Assert.Equal("Spaced Name Value", result);
- Assert.Equal(spacedVariableName, variable.Name);
- }
-
- [Fact]
- public async Task Should_Handle_Concurrent_Variable_Updates()
- {
- // Arrange - Test thread safety with concurrent updates
- var variable = new Variable("concurrentVar", 0, "concurrentVar");
- var tasks = new List>();
-
- // Act - Create multiple concurrent assignments
- for (int i = 1; i <= 10; i++)
- {
- var value = i;
- tasks.Add(Task.Run(async () =>
- {
- var setVariable = new SetVariable(variable, new Input(value, $"input{value}"));
- var context = await ActivityTestHelper.ExecuteActivityAsync(setVariable);
- return variable.Get(context);
- }));
- }
-
- var results = await Task.WhenAll(tasks);
-
- // Assert - All operations should complete successfully
- Assert.Equal(10, results.Length);
- Assert.All(results, result => Assert.True(result >= 1 && result <= 10));
- }
-}
-
-///
-/// Complex test object for serialization testing
-///
-public class ComplexTestObject
-{
- public int Id { get; set; }
- public string Name { get; set; } = string.Empty;
- public Dictionary Properties { get; set; } = new();
- public string[] Items { get; set; } = [];
}
\ No newline at end of file