Skip to content

Commit c1124a4

Browse files
authored
.NET: Add unit tests for declarative executor SetMultipleVariables (microsoft#2016)
* Add unit tests for create conversation executor * Update indentation and comment typo. * Added unit tests for declarative executor SetMultipleVariablesExecutor * Updated comments and syntactic sugar
1 parent e4185ca commit c1124a4

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System.Threading.Tasks;
4+
using Microsoft.Agents.AI.Workflows.Declarative.ObjectModel;
5+
using Microsoft.Bot.ObjectModel;
6+
using Microsoft.PowerFx.Types;
7+
using Xunit.Abstractions;
8+
9+
namespace Microsoft.Agents.AI.Workflows.Declarative.UnitTests.ObjectModel;
10+
11+
/// <summary>
12+
/// Tests for <see cref="SetMultipleVariablesExecutor"/>.
13+
/// </summary>
14+
public sealed class SetMultipleVariablesExecutorTest(ITestOutputHelper output) : WorkflowActionExecutorTest(output)
15+
{
16+
[Fact]
17+
public async Task SetMultipleVariablesAsync()
18+
{
19+
// Arrange, Act, Assert
20+
await this.ExecuteTestAsync(
21+
displayName: nameof(SetMultipleVariablesAsync),
22+
assignments: [
23+
new AssignmentCase("Variable1", new NumberDataValue(42), FormulaValue.New(42)),
24+
new AssignmentCase("Variable2", new StringDataValue("Test"), FormulaValue.New("Test")),
25+
new AssignmentCase("Variable3", new BooleanDataValue(true), FormulaValue.New(true))
26+
]);
27+
}
28+
29+
[Fact]
30+
public async Task SetMultipleVariablesWithExpressionsAsync()
31+
{
32+
// Arrange
33+
this.State.Set("SourceNumber", FormulaValue.New(10));
34+
this.State.Set("SourceText", FormulaValue.New("Hello"));
35+
this.State.Bind();
36+
37+
// Act, Assert
38+
await this.ExecuteTestAsync(
39+
displayName: nameof(SetMultipleVariablesWithExpressionsAsync),
40+
assignments: [
41+
new AssignmentCase("CalcVariable", ValueExpression.Expression("Local.SourceNumber * 2"), FormulaValue.New(20)),
42+
new AssignmentCase("ConcatVariable", ValueExpression.Expression(@"Concatenate(Local.SourceText, "" World"")"), FormulaValue.New("Hello World")),
43+
new AssignmentCase("BoolVariable", ValueExpression.Expression("Local.SourceNumber > 5"), FormulaValue.New(true))
44+
]);
45+
}
46+
47+
[Fact]
48+
public async Task SetMultipleVariablesWithVariableReferencesAsync()
49+
{
50+
// Arrange
51+
this.State.Set("Source1", FormulaValue.New(123));
52+
this.State.Set("Source2", FormulaValue.New("Reference"));
53+
this.State.Bind();
54+
55+
// Act, Assert
56+
await this.ExecuteTestAsync(
57+
displayName: nameof(SetMultipleVariablesWithVariableReferencesAsync),
58+
assignments: [
59+
new AssignmentCase("Target1", ValueExpression.Variable(PropertyPath.TopicVariable("Source1")), FormulaValue.New(123)),
60+
new AssignmentCase("Target2", ValueExpression.Variable(PropertyPath.TopicVariable("Source2")), FormulaValue.New("Reference"))
61+
]);
62+
}
63+
64+
[Fact]
65+
public async Task SetMultipleVariablesWithNullValuesAsync()
66+
{
67+
// Arrange, Act, Assert
68+
await this.ExecuteTestAsync(
69+
displayName: nameof(SetMultipleVariablesWithNullValuesAsync),
70+
assignments: [
71+
new AssignmentCase("NullVar1", null, FormulaValue.NewBlank()),
72+
new AssignmentCase("NormalVar", new StringDataValue("NotNull"), FormulaValue.New("NotNull")),
73+
new AssignmentCase("NullVar2", null, FormulaValue.NewBlank())
74+
]);
75+
}
76+
77+
[Fact]
78+
public async Task SetMultipleVariablesUpdateExistingAsync()
79+
{
80+
// Arrange
81+
this.State.Set("ExistingVar1", FormulaValue.New(999));
82+
this.State.Set("ExistingVar2", FormulaValue.New("OldValue"));
83+
84+
// Act, Assert
85+
await this.ExecuteTestAsync(
86+
displayName: nameof(SetMultipleVariablesUpdateExistingAsync),
87+
assignments: [
88+
new AssignmentCase("ExistingVar1", new NumberDataValue(111), FormulaValue.New(111)),
89+
new AssignmentCase("ExistingVar2", new StringDataValue("NewValue"), FormulaValue.New("NewValue")),
90+
new AssignmentCase("NewVar", new BooleanDataValue(false), FormulaValue.New(false))
91+
]);
92+
}
93+
94+
[Fact]
95+
public async Task SetMultipleVariablesEmptyAssignmentsAsync()
96+
{
97+
// Arrange
98+
SetMultipleVariables model = this.CreateModel(nameof(SetMultipleVariablesEmptyAssignmentsAsync), []);
99+
100+
// Arrange, Act, Assert
101+
Assert.Throws<DeclarativeModelException>(() =>
102+
{
103+
// Empty variables assignment should fail RequiredProperties validation.
104+
_ = new SetMultipleVariablesExecutor(model, this.State);
105+
});
106+
}
107+
108+
private async Task ExecuteTestAsync(string displayName, AssignmentCase[] assignments)
109+
{
110+
// Arrange
111+
SetMultipleVariables model = this.CreateModel(displayName, assignments);
112+
113+
// Act
114+
SetMultipleVariablesExecutor action = new(model, this.State);
115+
await this.ExecuteAsync(action);
116+
117+
// Assert
118+
VerifyModel(model, action);
119+
foreach (AssignmentCase assignment in assignments)
120+
{
121+
this.VerifyState(assignment.VariableName, assignment.ExpectedValue);
122+
}
123+
}
124+
125+
private SetMultipleVariables CreateModel(string displayName, AssignmentCase[] assignments)
126+
{
127+
SetMultipleVariables.Builder actionBuilder = new()
128+
{
129+
Id = this.CreateActionId(),
130+
DisplayName = this.FormatDisplayName(displayName),
131+
};
132+
133+
foreach (AssignmentCase assignment in assignments)
134+
{
135+
ValueExpression.Builder? valueExpressionBuilder = assignment.ValueExpression switch
136+
{
137+
null => null,
138+
DataValue dataValue => new ValueExpression.Builder(ValueExpression.Literal(dataValue)),
139+
ValueExpression valueExpression => new ValueExpression.Builder(valueExpression),
140+
_ => throw new System.ArgumentException($"Unsupported value type: {assignment.ValueExpression?.GetType().Name}")
141+
};
142+
143+
actionBuilder.Assignments.Add(new VariableAssignment.Builder()
144+
{
145+
Variable = PropertyPath.Create(FormatVariablePath(assignment.VariableName)),
146+
Value = valueExpressionBuilder,
147+
});
148+
}
149+
150+
return AssignParent<SetMultipleVariables>(actionBuilder);
151+
}
152+
153+
private sealed record AssignmentCase(string VariableName, object? ValueExpression, FormulaValue ExpectedValue);
154+
}

0 commit comments

Comments
 (0)