Skip to content

Commit 360f0ab

Browse files
author
Jack Kelliher
committed
Write test
1 parent 983ff52 commit 360f0ab

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

src/tests/Microsoft.PowerFx.Core.Tests.Shared/BinderTests.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Globalization;
77
using System.Linq;
88
using System.Linq.Expressions;
9+
using System.Numerics;
910
using System.Reflection.Metadata;
11+
using System.Text.RegularExpressions;
1012
using Microsoft.CodeAnalysis;
1113
using Microsoft.PowerFx.Core.App.Controls;
1214
using Microsoft.PowerFx.Core.Binding;
@@ -163,5 +165,90 @@ public void TestHasErrorsInTreeCallNode()
163165

164166
Assert.True(binding.ErrorContainer.HasErrorsInTree(binding.Top));
165167
}
168+
169+
/// <summary>
170+
/// Tests that variable volatility propagates to the children of As nodes.
171+
/// </summary>
172+
[Fact]
173+
public void TestVolatileVariablesWithForAllAsKeyword()
174+
{
175+
var config = new PowerFxConfig();
176+
config.SymbolTable.AddVariable(
177+
"volatileVariable",
178+
new KnownRecordType(TestUtils.DT("![DummyField:*[Value:n]]")),
179+
mutable: true);
180+
config.SymbolTable.AddVariable(
181+
"gblTable",
182+
new TableType(TestUtils.DT("*[Value:n]")),
183+
mutable: true);
184+
185+
config.AddFunction(new FakeSetFunction());
186+
187+
var engine = new Engine(config);
188+
var parserOptions = new ParserOptions { AllowsSideEffects = true };
189+
190+
const string expression = @"With(
191+
{dummyWith: gblTable},
192+
Set(
193+
volatileVariable,
194+
{DummyField: dummyWith}
195+
);
196+
ForAll(
197+
volatileVariable.DummyField| As currentRecord,
198+
currentRecord.Value + 1
199+
)
200+
)";
201+
202+
var indices = Regex.Matches(expression, Regex.Escape("|"))
203+
.Select(m => m.Index)
204+
.ToArray();
205+
206+
string result = Regex.Replace(expression, Regex.Escape("|"), string.Empty);
207+
var checkResult = engine.Check(result, parserOptions);
208+
Assert.True(checkResult.IsSuccess);
209+
210+
var binding = checkResult.Binding;
211+
212+
// Navigate to the ForAll node
213+
foreach (var index in indices)
214+
{
215+
var node = FindNodeVisitor.Run(checkResult.Binding.Top, index);
216+
Assert.True(binding.IsUnliftable(node));
217+
}
218+
}
219+
220+
private class FakeSetFunction : BuiltinFunction
221+
{
222+
public FakeSetFunction()
223+
: base(
224+
"Set",
225+
_ => "Mocks the set function",
226+
FunctionCategories.Behavior,
227+
DType.Boolean,
228+
0,
229+
2,
230+
2)
231+
{
232+
}
233+
234+
public override bool IsSelfContained => false;
235+
236+
public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures() =>
237+
Enumerable.Empty<TexlStrings.StringGetter[]>();
238+
239+
public override IEnumerable<Identifier> GetIdentifierOfModifiedValue(
240+
TexlNode[] args,
241+
out TexlNode identifierNode)
242+
{
243+
if (args.FirstOrDefault() is FirstNameNode { Ident: var ident } firstNameNode)
244+
{
245+
identifierNode = firstNameNode;
246+
return new List<Identifier> { ident };
247+
}
248+
249+
identifierNode = null;
250+
return null;
251+
}
252+
}
166253
}
167254
}

0 commit comments

Comments
 (0)