Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -707,22 +707,7 @@ public override bool CheckTypes(CheckTypesContext context, TexlNode[] args, DTyp
continue;
}

// Ensure that if the key in argument1 exists in the current record, their types match.
bool isSafeToUnion = true;
foreach (var typedName in curType.GetNames(DPath.Root))
{
DName name = typedName.Name;
if (recordType.TryGetType(name, out DType nameType) && !nameType.Accepts(typedName.Type, exact: true, useLegacyDateTimeAccepts: false, usePowerFxV1CompatibilityRules: context.Features.PowerFxV1CompatibilityRules))
{
errors.EnsureError(args[i], TexlStrings.ErrTypeError_Arg_Expected_Found, name, nameType.GetKindString(), typedName.Type.GetKindString());
isValid = isSafeToUnion = false;
}
}

if (isSafeToUnion)
{
retType = DType.Union(retType, curType, useLegacyDateTimeAccepts: false, context.Features);
}
retType = DType.Union(retType, curType, useLegacyDateTimeAccepts: false, context.Features);
}

returnType = retType;
Expand Down
57 changes: 45 additions & 12 deletions src/tests/Microsoft.PowerFx.Core.Tests.Shared/TexlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4559,18 +4559,51 @@ public void TexlFunctionTypeSemanticsTable_PageableInputs(string script, string
[InlineData("Abs(Type(Number))", "n")]
[InlineData("If(Type(Boolean), 1, 2)", "n")]
[InlineData("Concatenate(Type(Text))", "s")]
public void TestTypeLiteralsNegative(string script, string expectedSchema)
{
TestBindingErrors(
script,
TestUtils.DT(expectedSchema),
features: Features.PowerFxV1);
}

[Theory]

// Exact type match: all arguments directly match the data source schema *[Name:s, Value:n]
[InlineData("Patch(MyDataSource, MyRecord, { Name: \"Hello\", Value: 1 })", true)]
public void TestTypeLiteralsNegative(string script, string expectedSchema)
{
TestBindingErrors(
script,
TestUtils.DT(expectedSchema),
features: Features.PowerFxV1);
}

[Theory]
[InlineData("Patch({a:1}, {b:2})", "![a:n, b:n]")]
[InlineData("Patch({a:1}, {b:\"test\"})", "![a:n, b:s]")]
[InlineData("Patch({a:1, b:2}, {b:\"3\", c:4})", "![a:n, b:s, c:n]")]
[InlineData("Patch({x:true}, {y:Date(2020,1,1)})", "![x:b, y:D]")]
public void TestPatchRecordFunction(string script, string expectedType)
{
Assert.True(DType.TryParse(expectedType, out var type), script);
Assert.True(type.IsValid, script);

TestSimpleBindingSuccess(script, type);
}

[Theory]
[InlineData("Patch(rec1, {b:2})", "![a:n, b:n]", "![a:n]", "rec1")]
[InlineData("Patch(rec2, {c:\"new\"})", "![a:n, b:s, c:s]", "![a:n, b:s]", "rec2")]
[InlineData("Patch(rec3, {b:3, c:4})", "![a:n, b:n, c:n]", "![a:n, b:n]", "rec3")]
[InlineData("Patch(rec4, {y:Date(2020,1,1)})", "![x:b, y:D]", "![x:b]", "rec4")]
[InlineData("Patch(rec5, {x:123})", "![x:$]", "![x:$]", "rec5")]
public void TestPatchRecordFunctionWithVariable(string script, string expectedType, string variableType, string variableName)
{
Assert.True(DType.TryParse(expectedType, out var type), script);
Assert.True(type.IsValid, script);

Assert.True(DType.TryParse(variableType, out var varType), script);
Assert.True(varType.IsValid, script);

var symbol = new SymbolTable();
symbol.AddVariable(variableName, FormulaType.Build(varType));

TestSimpleBindingSuccess(script, type, symbol);
}

[Theory]

// Exact type match: all arguments directly match the data source schema *[Name:s, Value:n]
[InlineData("Patch(MyDataSource, MyRecord, { Name: \"Hello\", Value: 1 })", true)]

// Exact type match: all arguments directly match the data source schema using display names
[InlineData("Patch(MyDataSource, MyRecord, { DisplayNameForName: \"Hello\", DisplayNameForValue: 1 })", true)]
Expand Down
Loading