From 0b9465329332d4f84233b464f493e50b734211fc Mon Sep 17 00:00:00 2001 From: "Anderson Ferreira da Silva (from Dev Box)" Date: Fri, 1 Mar 2024 00:23:58 -0600 Subject: [PATCH] Saving progress. IR translator, removing unnacessary PFxV1Disabled test cases. --- .../Microsoft.PowerFx.Core/IR/CoercionKind.cs | 3 +- .../IR/CoercionMatrix.cs | 6 + .../Microsoft.PowerFx.Core/IR/IRTranslator.cs | 3 + .../IR/Nodes/UnaryOpKind.cs | 3 +- .../Texl/Builtins/Collect.cs | 200 ++++++--- .../Microsoft.PowerFx.Core/Types/DType.cs | 2 +- .../Utils/MutationUtils.cs | 15 + .../Functions/LibraryMutation.cs | 40 +- .../Functions/LibraryUnary.cs | 21 +- .../ExpressionTestCases/Clear.txt | 6 - .../ExpressionTestCases/Clear_V1Compat.txt | 6 + .../ExpressionTestCases/Collect.txt | 39 -- .../ExpressionTestCases/Collect_V1Compat.txt | 30 ++ .../Collect_V1CompatDisabled.txt | 43 -- .../ExpressionTestCases/DecimalBoot.txt | 3 - .../ExpressionTestCases/Patch.txt | 37 -- .../ExpressionTestCases/Patch_V1Compat.txt | 37 ++ .../Patch_V1CompatDisabled.txt | 12 - .../ExpressionTestCases/Remove.txt | 2 +- .../MutationFunctionsTests.cs | 26 ++ .../AndOr_V1CompatDisabled.txt | 18 +- .../Coalesce_CoalesceShortCircuitDisabled.txt | 38 +- .../MutationScripts/Collect.txt | 2 +- .../DeepMutation_V1CompatDisabled.txt | 412 ------------------ .../ForAllMutate_V1CompatDisabled.txt | 107 ----- .../IfError_V1CompatDisabled.txt | 47 -- .../MutationScripts/Set_V1CompatDisabled.txt | 273 ------------ .../Switch_V1CompatDisabled.txt | 54 --- 28 files changed, 330 insertions(+), 1155 deletions(-) delete mode 100644 src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect.txt delete mode 100644 src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1CompatDisabled.txt delete mode 100644 src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/DeepMutation_V1CompatDisabled.txt delete mode 100644 src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/ForAllMutate_V1CompatDisabled.txt delete mode 100644 src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/IfError_V1CompatDisabled.txt delete mode 100644 src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Set_V1CompatDisabled.txt delete mode 100644 src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Switch_V1CompatDisabled.txt diff --git a/src/libraries/Microsoft.PowerFx.Core/IR/CoercionKind.cs b/src/libraries/Microsoft.PowerFx.Core/IR/CoercionKind.cs index d352851155..0de57192c7 100644 --- a/src/libraries/Microsoft.PowerFx.Core/IR/CoercionKind.cs +++ b/src/libraries/Microsoft.PowerFx.Core/IR/CoercionKind.cs @@ -107,6 +107,7 @@ internal enum CoercionKind CurrencyToText, TextToCurrency, CurrencyToBoolean, - BooleanToCurrency, + BooleanToCurrency, + PrimitiveToSingleColumnRecord, } } diff --git a/src/libraries/Microsoft.PowerFx.Core/IR/CoercionMatrix.cs b/src/libraries/Microsoft.PowerFx.Core/IR/CoercionMatrix.cs index e521971068..c75c9b355c 100644 --- a/src/libraries/Microsoft.PowerFx.Core/IR/CoercionMatrix.cs +++ b/src/libraries/Microsoft.PowerFx.Core/IR/CoercionMatrix.cs @@ -22,6 +22,12 @@ public static CoercionKind GetCoercionKind(DType fromType, DType toType, bool us if (fromType.IsAggregate && toType.Kind == DKind.DataEntity) { return CoercionKind.AggregateToDataEntity; + } + + // Coercion from a primitive type to a single column record type. + if (fromType.IsPrimitive && toType.IsRecord) + { + return CoercionKind.PrimitiveToSingleColumnRecord; } if (toType.IsLargeImage && (fromType.Kind == DKind.Image || fromType == DType.MinimalLargeImage)) diff --git a/src/libraries/Microsoft.PowerFx.Core/IR/IRTranslator.cs b/src/libraries/Microsoft.PowerFx.Core/IR/IRTranslator.cs index 7b8afea7be..f73a53644c 100644 --- a/src/libraries/Microsoft.PowerFx.Core/IR/IRTranslator.cs +++ b/src/libraries/Microsoft.PowerFx.Core/IR/IRTranslator.cs @@ -1179,6 +1179,9 @@ private IntermediateNode InjectCoercion(IntermediateNode child, IRTranslatorCont break; case CoercionKind.PenImageToText: unaryOpKind = UnaryOpKind.PenImageToText; + break; + case CoercionKind.PrimitiveToSingleColumnRecord: + unaryOpKind = UnaryOpKind.PrimitiveToSingleColumnRecord; break; case CoercionKind.UntypedToText: return new CallNode(IRContext.NotInSource(FormulaType.Build(toType)), BuiltinFunctionsCore.Text_UO, child); diff --git a/src/libraries/Microsoft.PowerFx.Core/IR/Nodes/UnaryOpKind.cs b/src/libraries/Microsoft.PowerFx.Core/IR/Nodes/UnaryOpKind.cs index 4fa2837382..dfa45df0ef 100644 --- a/src/libraries/Microsoft.PowerFx.Core/IR/Nodes/UnaryOpKind.cs +++ b/src/libraries/Microsoft.PowerFx.Core/IR/Nodes/UnaryOpKind.cs @@ -98,7 +98,8 @@ internal enum UnaryOpKind DateToDateTime, BooleanToOptionSet, - AggregateToDataEntity, + AggregateToDataEntity, + PrimitiveToSingleColumnRecord, // Argument pre-processesor in IR Phase. diff --git a/src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Collect.cs b/src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Collect.cs index 8c9ffc786c..171dbdc772 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Collect.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/Collect.cs @@ -91,15 +91,74 @@ protected CollectFunction(string name, TexlStrings.StringGetter description) return base.GetSignatures(arity); } - public virtual DType GetCollectedType(PowerFx.Features features, DType argType) + public virtual DType GetCollectedType(Features features, DType argType, TexlNode arg, ref Dictionary nodeToCoercedTypeMap) { Contracts.Assert(argType.IsValid); return argType; + } + + public bool TryGetUnifiedCollectedTypeCanvas(TexlNode[] args, DType[] argTypes, IErrorContainer errors, Features features, out DType collectedType, ref Dictionary nodeToCoercedTypeMap) + { + Contracts.AssertValue(args); + Contracts.AssertAllValues(args); + Contracts.AssertValue(argTypes); + Contracts.Assert(args.Length == argTypes.Length); + Contracts.AssertValue(errors); + Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity); + + bool fValid = true; + DType itemType = DType.Invalid; + + var argc = args.Length; + + for (int i = 1; i < argc; i++) + { + DType argType = GetCollectedType(features, argTypes[i], args[i], ref nodeToCoercedTypeMap); + + // The subsequent args should all be aggregates. + if (!argType.IsAggregate) + { + errors.EnsureError(args[i], TexlStrings.ErrBadType_Type, argType.GetKindString()); + fValid = false; + continue; + } + + // Promote the arg type to a table to facilitate unioning. + if (!argType.IsTable) + { + argType = argType.ToTable(); + } + + if (!itemType.IsValid) + { + itemType = argType; + } + else + { + bool fUnionError = false; + itemType = DType.Union(ref fUnionError, itemType, argType, useLegacyDateTimeAccepts: true, features); + if (fUnionError) + { + errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrIncompatibleTypes); + fValid = false; + } + } + + // We only support accessing entities in collections if the collection has only 1 argument that contributes to it's type + if (argc != 2 && itemType.ContainsDataEntityType(DPath.Root)) + { + fValid &= DropAllOfKindNested(ref itemType, errors, args[i], DKind.DataEntity); + } + } + + Contracts.Assert(!itemType.IsValid || itemType.IsTable); + collectedType = itemType.IsValid ? itemType.ToTable() : DType.EmptyTable; + return fValid; } // Attempt to get the unified schema of the items being collected by an invocation. - private bool TryGetUnifiedCollectedType(CheckTypesContext context, TexlNode[] args, DType[] argTypes, IErrorContainer errors, out DType collectedType) + private bool TryGetUnifiedCollectedTypeV1(TexlNode[] args, DType[] argTypes, IErrorContainer errors, Features features, out DType collectedType, ref Dictionary nodeToCoercedTypeMap) { Contracts.AssertValue(args); Contracts.AssertAllValues(args); @@ -117,7 +176,13 @@ private bool TryGetUnifiedCollectedType(CheckTypesContext context, TexlNode[] ar for (var i = 1; i < argc; i++) { - DType argType = GetCollectedType(context.Features, argTypes[i]); + DType argType = GetCollectedType(features, argTypes[i], args[i], ref nodeToCoercedTypeMap); + + // !!! How is it possible for an argtype to be a primitive and an aggregate at the same time? + //if (argType.DisplayNameProvider == null && argType.Kind == DKind.ObjNull) + //{ + // argType.DisplayNameProvider = datasourceType.DisplayNameProvider; + //} // The subsequent args should all be aggregates. if (!argType.IsAggregate) @@ -128,13 +193,13 @@ private bool TryGetUnifiedCollectedType(CheckTypesContext context, TexlNode[] ar } // Promote the arg type to a table to facilitate unioning. - if (!argType.IsRecord) + if (!argType.IsTable) { - argType = argType.ToRecord(); + argType = argType.ToTable(); } // Checks if all record names exist against table type and if its possible to coerce. - bool checkAggregateNames = argType.CheckAggregateNames(datasourceType, args[i], errors, context.Features, SupportsParamCoercion); + bool checkAggregateNames = argType.CheckAggregateNames(datasourceType, args[i], errors, features, SupportsParamCoercion); fValid = fValid && checkAggregateNames; if (!itemType.IsValid) @@ -144,7 +209,7 @@ private bool TryGetUnifiedCollectedType(CheckTypesContext context, TexlNode[] ar else { var fUnionError = false; - itemType = DType.Union(ref fUnionError, itemType, argType, useLegacyDateTimeAccepts: true, context.Features); + itemType = DType.Union(ref fUnionError, itemType, argType, useLegacyDateTimeAccepts: true, features); if (fUnionError) { errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrIncompatibleTypes); @@ -159,8 +224,8 @@ private bool TryGetUnifiedCollectedType(CheckTypesContext context, TexlNode[] ar } } - Contracts.Assert(!itemType.IsValid || itemType.IsRecord); - collectedType = itemType.IsValid ? itemType : DType.EmptyRecord; + Contracts.Assert(!itemType.IsValid || itemType.IsTable); + collectedType = itemType.IsValid ? itemType : DType.EmptyTable; return fValid; } @@ -182,51 +247,44 @@ public override bool CheckTypes(CheckTypesContext context, TexlNode[] args, DTyp { errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrInvalidArgs_Func, Name); fValid = false; - } + } + + DType collectedType = null; // Get the unified collected type on the RHS. This will generate appropriate - // document errors for invalid arguments such as unsupported aggregate types. - fValid &= TryGetUnifiedCollectedType(context, args, argTypes, errors, out DType collectedType); - Contracts.Assert(collectedType.IsRecord); - - if (fValid) - { - if (!collectedType.TryGetCoercionSubType(collectionType, out DType coercionType, out var coercionNeeded, context.Features)) - { - fValid = false; - } - else - { - if (coercionNeeded) - { - CollectionUtils.Add(ref nodeToCoercedTypeMap, args[1], coercionType); - } - - var fError = false; - - returnType = DType.Union(ref fError, collectionType.ToRecord(), collectedType, useLegacyDateTimeAccepts: false, context.Features, allowCoerce: true); - - if (fError) - { - fValid = false; - if (!SetErrorForMismatchedColumns(collectionType, collectedType, args[1], errors, context.Features)) - { - errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrTableDoesNotAcceptThisType); - } - } - } - } - - if (context.Features.PowerFxV1CompatibilityRules && argTypes.Length == 2) - { - if (argTypes[1].IsTable && argTypes[1].Kind != DKind.ObjNull) - { - returnType = returnType.ToTable(); - } - } - else - { - returnType = returnType.ToTable(); + // document errors for invalid arguments such as unsupported aggregate types. + if (context.Features.PowerFxV1CompatibilityRules) + { + fValid &= TryGetUnifiedCollectedTypeV1(args, argTypes, errors, context.Features, out collectedType, ref nodeToCoercedTypeMap); + } + else + { + fValid &= TryGetUnifiedCollectedTypeCanvas(args, argTypes, errors, context.Features, out collectedType, ref nodeToCoercedTypeMap); + } + + Contracts.Assert(collectedType.IsTable); + + bool fError = false; + returnType = DType.Union(ref fError, collectionType, collectedType, useLegacyDateTimeAccepts: true, context.Features); + if (fError) + { + fValid = false; + if (!SetErrorForMismatchedColumns(collectionType, collectedType, args[1], errors, context.Features)) + { + errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrTableDoesNotAcceptThisType); + } + } + + if (fValid) + { + if (context.Features.PowerFxV1CompatibilityRules && argTypes.Length == 2 && (argTypes[1].IsRecord || argTypes[1].IsPrimitive)) + { + returnType = returnType.ToRecord(); + } + else + { + returnType = returnType.ToTable(); + } } return fValid; @@ -323,8 +381,22 @@ public override bool IsAsyncInvocation(CallNode callNode, TexlBinding binding) return Arg0RequiresAsync(callNode, binding); } - public static DType GetCollectedTypeForGivenArgType(Features features, DType argType) + public static DType GetCollectedTypeForGivenArgType(Features features, DType argType, TexlNode arg, ref Dictionary nodeToCoercedTypeMap) { + var singleColumnRecordType = GetCollectedTypeForGivenArgType(features, argType); + + if (!argType.IsPrimitive) + { + return argType; + } + + CollectionUtils.Add(ref nodeToCoercedTypeMap, arg, singleColumnRecordType); + + return singleColumnRecordType; + } + + public static DType GetCollectedTypeForGivenArgType(Features features, DType argType) + { Contracts.Assert(argType.IsValid); if (!argType.IsPrimitive) @@ -333,7 +405,7 @@ public static DType GetCollectedTypeForGivenArgType(Features features, DType arg } // Passed a scalar; make a record out of it, using a name that depends on the type. - string fieldName = Contracts.VerifyValue(CreateInvariantFieldName(features, argType.Kind)); + var fieldName = Contracts.VerifyValue(CreateInvariantFieldName(features, argType.Kind)); return DType.CreateRecord(new TypedName[] { new TypedName(argType, new DName(fieldName)) }); } @@ -341,21 +413,7 @@ protected static string CreateInvariantFieldName(PowerFx.Features features, DKin { Contracts.Assert(dKind >= DKind._Min && dKind < DKind._Lim); - return GetScalarSingleColumnNameForType(features, dKind); - } - - private static string GetScalarSingleColumnNameForType(Features features, DKind kind) - { - return kind switch - { - DKind.Image or - DKind.Hyperlink or - DKind.Media or - DKind.Blob or - DKind.PenImage => features.ConsistentOneColumnTableResult ? TableValue.ValueName : "Url", - - _ => TableValue.ValueName - }; + return MutationUtils.GetScalarSingleColumnNameForType(features, dKind); } } @@ -373,9 +431,9 @@ public static string GetInvariantNameForRecord(PowerFx.Features features, DKind return CreateInvariantFieldName(features, dKind); } - public override DType GetCollectedType(PowerFx.Features features, DType argType) + public override DType GetCollectedType(Features features, DType argType, TexlNode arg, ref Dictionary nodeToCoercedTypeMap) { - return GetCollectedTypeForGivenArgType(features, argType); + return GetCollectedTypeForGivenArgType(features, argType, arg, ref nodeToCoercedTypeMap); } } } diff --git a/src/libraries/Microsoft.PowerFx.Core/Types/DType.cs b/src/libraries/Microsoft.PowerFx.Core/Types/DType.cs index d37679f0f6..7ad289bd79 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Types/DType.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Types/DType.cs @@ -144,7 +144,7 @@ public static IEnumerable GetPrimitiveTypes() /// Eventually, all display names should come from this centralized source. /// We should not be using individual DataSource/OptionSet/View references. /// - internal DisplayNameProvider DisplayNameProvider { get; private set; } + internal DisplayNameProvider DisplayNameProvider { get; set; } /// /// NamedValueKind is used only for values of kind NamedValue diff --git a/src/libraries/Microsoft.PowerFx.Core/Utils/MutationUtils.cs b/src/libraries/Microsoft.PowerFx.Core/Utils/MutationUtils.cs index cf5d4fe3c4..db9c7c198e 100644 --- a/src/libraries/Microsoft.PowerFx.Core/Utils/MutationUtils.cs +++ b/src/libraries/Microsoft.PowerFx.Core/Utils/MutationUtils.cs @@ -10,6 +10,7 @@ using Microsoft.PowerFx.Core.Localization; using Microsoft.PowerFx.Core.Types; using Microsoft.PowerFx.Syntax; +using Microsoft.PowerFx.Types; namespace Microsoft.PowerFx.Core.Utils { @@ -62,6 +63,20 @@ public static void CheckSemantics(TexlBinding binding, TexlFunction function, Te errors.EnsureError(targetArg, TexlStrings.ErrInvalidArgs_Func, function.Name); return; } + } + + public static string GetScalarSingleColumnNameForType(Features features, DKind kind) + { + return kind switch + { + DKind.Image or + DKind.Hyperlink or + DKind.Media or + DKind.Blob or + DKind.PenImage => features.ConsistentOneColumnTableResult ? TableValue.ValueName : "Url", + + _ => TableValue.ValueName + }; } } } diff --git a/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryMutation.cs b/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryMutation.cs index dcbf58846a..9438104bf5 100644 --- a/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryMutation.cs +++ b/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryMutation.cs @@ -8,6 +8,8 @@ using System.Threading.Tasks; using Microsoft.PowerFx.Core.Functions; using Microsoft.PowerFx.Core.IR; +using Microsoft.PowerFx.Core.Types; +using Microsoft.PowerFx.Core.Utils; using Microsoft.PowerFx.Functions; using Microsoft.PowerFx.Interpreter; using Microsoft.PowerFx.Types; @@ -36,8 +38,12 @@ internal async Task Process(IServiceProvider runtimeServiceProvide { FormulaValue arg0; var argc = args.Length; - var returnIsTable = irContext._type.IsTable; - var features = runtimeServiceProvider.GetService(); + var features = runtimeServiceProvider.GetService(); + + if (!features.PowerFxV1CompatibilityRules) + { + throw new InvalidOperationException("Collect funtion can only be executed if PowerFx V1 feature is active."); + } // Need to check if the Lazy first argument has been evaluated since it may have already been // evaluated in the ClearCollect case. @@ -96,37 +102,27 @@ internal async Task Process(IServiceProvider runtimeServiceProvide } else if (arg is RecordValue) { - var recordValueCopy = (RecordValue)arg.MaybeShallowCopy(); + var recordValueCopy = CompileTimeTypeWrapperRecordValue.AdjustType(tableValue.Type.ToRecord(), (RecordValue)arg.MaybeShallowCopy()); resultRows.Add(await tableValue.AppendAsync(recordValueCopy, cancellationToken).ConfigureAwait(false)); } else if (arg is ErrorValue) { return arg; } - else if (arg is BlankValue && !tableValue.Type._type.IsSingleColumnTable) - { - continue; - } - else - { - // If arg is a scalar value, then we need to create a single column record. - NamedValue namedValue = new NamedValue(tableValue.Type.SingleColumnFieldName, arg); - var singleColumnRecord = FormulaValue.NewRecordFromFields(namedValue); - - resultRows.Add(await tableValue.AppendAsync(singleColumnRecord, cancellationToken).ConfigureAwait(false)); - } - } - - if (!features.PowerFxV1CompatibilityRules) - { - return tableValue; + + // !!! How to handle BlankValue? + //else if (arg is BlankValue && !tableValue.Type._type.IsSingleColumnTable) + //{ + // continue; + //} } if (resultRows.Count == 0) { return FormulaValue.NewBlank(arg0.Type); - } - else if (returnIsTable) + } + + if (irContext._type.IsTable) { return CompileTimeTypeWrapperTableValue.AdjustType(tableValue.Type, new InMemoryTableValue(IRContext.NotInSource(arg0.Type), resultRows)); } diff --git a/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryUnary.cs b/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryUnary.cs index 5d6b44796f..76ce28d25a 100644 --- a/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryUnary.cs +++ b/src/libraries/Microsoft.PowerFx.Interpreter/Functions/LibraryUnary.cs @@ -523,6 +523,17 @@ internal static partial class Library checkRuntimeValues: DeferRuntimeValueChecking, returnBehavior: ReturnBehavior.ReturnBlankIfAnyArgIsBlank, targetFunction: UntypedStringToUntypedDecimal) + }, + { + UnaryOpKind.PrimitiveToSingleColumnRecord, + StandardErrorHandling( + functionName: null, // internal function, no user-facing name + expandArguments: NoArgExpansion, + replaceBlankValues: DoNotReplaceBlank, + checkRuntimeTypes: ExactValueTypeOrBlank, + checkRuntimeValues: DeferRuntimeValueChecking, + returnBehavior: ReturnBehavior.AlwaysEvaluateAndReturnResult, + targetFunction: PrimitiveToSingleColumnRecord) }, }; #endregion @@ -1027,7 +1038,13 @@ public static FormulaValue BlankToEmptyString(IRContext irContext, FormulaValue[ } return args[0]; - } -#endregion + } + + public static FormulaValue PrimitiveToSingleColumnRecord(IRContext irContext, FormulaValue[] args) + { + var record = FormulaValue.NewRecordFromFields(new NamedValue("Value", args[0])); + return record; + } + #endregion } } diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear.txt index 2a63593c15..d1edfa0e33 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear.txt @@ -5,12 +5,6 @@ >> Clear(t1);CountRows(t1) 0 ->> Collect(t1, r2); - Collect(t1, {Field1:3,Field2:"mars",Field3:DateTime(2022,3,1,0,0,0,0),Field4:false}); - Clear(t1); - If(CountRows(t1) = 0, "Cleared", "Failed") -"Cleared" - >> Clear() Errors: Error 0-7: Invalid number of arguments: received 0, expected 1. diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear_V1Compat.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear_V1Compat.txt index dd3efec4b4..2cb3a0469f 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear_V1Compat.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Clear_V1Compat.txt @@ -17,3 +17,9 @@ Errors: Error 14-15: Invalid argument type (Decimal). Expecting a Table value in >> Clear(t1);Clear(t2) If(true, {test:1}, "Void value (result of the expression can't be used).") + +>> Collect(t1, r2); + Collect(t1, {Field1:3,Field2:"mars",Field3:DateTime(2022,3,1,0,0,0,0),Field4:false}); + Clear(t1); + If(CountRows(t1) = 0, "Cleared", "Failed") +"Cleared" diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect.txt deleted file mode 100644 index 1292dc2f0a..0000000000 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect.txt +++ /dev/null @@ -1,39 +0,0 @@ -#SETUP: EnableExpressionChaining,MutationFunctionsTestSetup - -// Check MutationFunctionsTestSetup handler (PowerFxEvaluationTests.cs) for documentation. - ->> Collect(t1, r2);CountRows(t1) -2 - ->> Collect(t1, r2);Collect(t1, {Field1:3,Field2:"mars",Field3:DateTime(2022,3,1,0,0,0,0),Field4:false});CountRows(t1) -3 - ->> Collect(t1, {Field1:3});Last(t1).Field2 -Blank() - ->> Collect(t1, If(1>0, r2));CountRows(t1) -2 - ->> IsError(Collect(t1, If(1/0, r2))) -true - ->> Collect(t1) -Errors: Error 0-11: Invalid number of arguments: received 1, expected 2 or more. - ->> Collect(t1, "x") -Errors: Error 0-16: The function 'Collect' has some invalid arguments.|Error 12-15: Invalid argument type. Cannot use Text values in this context. - ->> Collect(t1, 1) -Errors: Error 0-14: The function 'Collect' has some invalid arguments.|Error 12-13: Invalid argument type. Cannot use Decimal values in this context. - ->> Collect(Foo,r2) -Errors: Error 8-11: Name isn't valid. 'Foo' isn't recognized.|Error 12-14: The specified column 'Field1' does not exist.|Error 0-15: The function 'Collect' has some invalid arguments. - ->> Collect(Foo,Bar) -Errors: Error 8-11: Name isn't valid. 'Foo' isn't recognized.|Error 12-15: Name isn't valid. 'Bar' isn't recognized.|Error 0-16: The function 'Collect' has some invalid arguments. - ->> Collect(1/0,Foo) -Errors: Error 12-15: Name isn't valid. 'Foo' isn't recognized. - ->> Collect(t1,{Price:200}).Price -Errors: Error 11-22: The specified column 'Price' does not exist.|Error 0-23: The function 'Collect' has some invalid arguments.|Error 23-29: Name isn't valid. 'Price' isn't recognized. \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1Compat.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1Compat.txt index 0bfe631858..a693f49780 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1Compat.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1Compat.txt @@ -1,5 +1,20 @@ #SETUP: EnableExpressionChaining,MutationFunctionsTestSetup,PowerFxV1CompatibilityRules +>> Collect(t1, r2);CountRows(t1) +2 + +>> Collect(t1, r2);Collect(t1, {Field1:3,Field2:"mars",Field3:DateTime(2022,3,1,0,0,0,0),Field4:false});CountRows(t1) +3 + +>> Collect(t1, {Field1:3});Last(t1).Field2 +Blank() + +>> Collect(t1, If(1>0, r2));CountRows(t1) +2 + +>> IsError(Collect(t1, If(1/0, r2))) +true + >> Collect(t_name, {name: "textInput1"}) {name:"textInput1"} @@ -44,3 +59,18 @@ Table({Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{F >> Collect(t1, Table(r2,r2), {Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) Table({Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) + +>> Collect(t1, "x") +Errors: Error 0-16: The function 'Collect' has some invalid arguments.|Error 12-15: Invalid argument type. Cannot use Text values in this context. + +>> Collect(Foo,r2) +Errors: Error 8-11: Name isn't valid. 'Foo' isn't recognized.|Error 12-14: The specified column 'Field1' does not exist.|Error 0-15: The function 'Collect' has some invalid arguments. + +>> Collect(Foo,Bar) +Errors: Error 8-11: Name isn't valid. 'Foo' isn't recognized.|Error 12-15: Name isn't valid. 'Bar' isn't recognized.|Error 0-16: The function 'Collect' has some invalid arguments. + +>> Collect(1/0,Foo) +Errors: Error 12-15: Name isn't valid. 'Foo' isn't recognized. + +>> Collect(t1,{Price:200}).Price +Errors: Error 0-23: The function 'Collect' has some invalid arguments.|Error 11-22: The specified column 'Price' does not exist. diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1CompatDisabled.txt deleted file mode 100644 index 8ffb9284ff..0000000000 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Collect_V1CompatDisabled.txt +++ /dev/null @@ -1,43 +0,0 @@ -#SETUP: EnableExpressionChaining,MutationFunctionsTestSetup,disable:PowerFxV1CompatibilityRules - ->> Collect(FirstN(t_name, 0), {name: "textInput1"}) -Table({name:"textInput1"}) - ->> Collect(t1, {Field1:3,Field2:"mars",Field3:DateTime(2022,3,1,0,0,0,0),Field4:false}) -Table({Field1:1,Field2:"earth",Field3:DateTime(2022,1,1,0,0,0,0),Field4:true},{Field1:3,Field2:"mars",Field3:DateTime(2022,3,1,0,0,0,0),Field4:false}) - ->> Last(Collect(t_empty,{Value:200})).Value -200 - ->> Collect(Table({name: "VC"}), {surname: "textInput1"}) -Errors: Error 29-52: The specified column 'surname' does not exist. The column with the most similar name is 'name'.|Error 0-53: The function 'Collect' has some invalid arguments. - ->> Collect(Error({Kind:ErrorKind.Custom}), r2) -Errors: Error 40-42: The specified column 'Field1' does not exist.|Error 0-43: The function 'Collect' has some invalid arguments. - ->> Collect(Error({Kind:ErrorKind.Custom}), Error({Kind:ErrorKind.Div0})) -Error({Kind:ErrorKind.Custom}) - ->> Collect(Blank(), r2) -Errors: Error 17-19: The specified column 'Field1' does not exist.|Error 0-20: The function 'Collect' has some invalid arguments. - ->> Collect(Blank(), Blank()) -Blank() - ->> Collect("", "") -Errors: Error 0-15: The function 'Collect' has some invalid arguments.|Error 8-10: Invalid argument type (Text). Expecting a Table value instead.|Error 12-14: Invalid argument type. Cannot use Text values in this context. - ->> IsBlank(Collect(t1, Blank())) -false - ->> Collect(t1, r2, r2) -Table({Field1:1,Field2:"earth",Field3:DateTime(2022,1,1,0,0,0,0),Field4:true},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) - ->> Collect(t1, r2, 1; 2; r2) -Table({Field1:1,Field2:"earth",Field3:DateTime(2022,1,1,0,0,0,0),Field4:true},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) - ->> Collect(t1, Table(r2,r2)) -Table({Field1:1,Field2:"earth",Field3:DateTime(2022,1,1,0,0,0,0),Field4:true},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) - ->> Collect(t1, Table(r2,r2), {Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) -Table({Field1:1,Field2:"earth",Field3:DateTime(2022,1,1,0,0,0,0),Field4:true},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false},{Field1:2,Field2:"moon",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}) \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/DecimalBoot.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/DecimalBoot.txt index 4bd34fcbe5..69469a8d6b 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/DecimalBoot.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/DecimalBoot.txt @@ -13,9 +13,6 @@ Blank() >> Boolean(Filter([1,2,3], Value > 10)) Table() ->> ForAll(Sequence(5), Collect(t_empty, {Value:ThisRecord.Value})); ForAll(Sequence(CountRows(t_empty)), Collect(t_empty2, Index(t_empty, ThisRecord.Value))); Patch(t_empty, First(t_empty), {Value:99}); Patch(t_empty2, Last(t_empty2), {Value:88}); Concat(t_empty, Value) & "," & Concat(t_empty2, Value) -"992345,123488" - >> ForAll(Boolean([3, 1/0, 0, Sqrt(-1)]), IfError(Text(Value), $"ErrorKind={FirstError.Kind}")) Table({Value:"true"},{Value:"ErrorKind=13"},{Value:"false"},{Value:"ErrorKind=24"}) diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch.txt index 4667e95037..bcd3ba967c 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch.txt @@ -42,10 +42,6 @@ Errors: Error 14-31: The specified column 'Field5' does not exist.|Error 0-32: T >> Patch(t1, First(t1), {Field2:"Venus"}).Field2 "Venus" ->> Collect(t1, r2); - Patch(t1, Last(t1), {Field1:10}, {Field2:"Venus"}, {Field4:true}).Field1 -10 - >> If(Patch(t1, First(t1), {Field4:false}).Field4, 1,0) 0 @@ -98,22 +94,6 @@ Errors: Error 45-78: The type of this argument 'Field3' does not match the expec >> Patch(t1,LookUp(t1,DisplayNameField2="earth"),{Field1:100,Field4:false});t1 Table({Field1:100,Field2:"earth",Field3:DateTime(2022,1,1,0,0,0,0),Field4:false}) ->> Collect(t1, r2); - Collect(t1, {Field1:3,Field2:"venus",Field3:DateTime(2030,1,1,0,0,0,0),Field4:true}); - Collect(t1, {Field1:4,Field2:"mars",Field3:DateTime(2031,1,1,0,0,0,0),Field4:false}); - Collect(t1, {Field1:5,Field2:"jupter",Field3:DateTime(2032,1,1,0,0,0,0),Field4:true}); - Collect(t1, {Field1:6,Field2:"saturn",Field3:DateTime(2033,1,1,0,0,0,0),Field4:false}); - Patch(t1, First(Filter(t1, Field1 > 4)), {Field2: "phobos"}); -{Field1:5,Field2:"phobos",Field3:DateTime(2032,1,1,0,0,0,0),Field4:true} - ->> Collect(t1, r2); - Collect(t1, {DisplayNameField1:3,Field2:"venus",Field3:DateTime(2030,1,1,0,0,0,0),DisplayNameField4:true}); - Collect(t1, {DisplayNameField1:4,Field2:"mars",Field3:DateTime(2031,1,1,0,0,0,0),DisplayNameField4:false}); - Collect(t1, {DisplayNameField1:5,Field2:"jupter",Field3:DateTime(2032,1,1,0,0,0,0),DisplayNameField4:true}); - Collect(t1, {DisplayNameField1:6,Field2:"saturn",Field3:DateTime(2033,1,1,0,0,0,0),DisplayNameField4:false}); - Patch(t1, Last(Filter(t1, Field4 = false)), {DisplayNameField2: "phobos"}); -{Field1:6,Field2:"phobos",Field3:DateTime(2033,1,1,0,0,0,0),Field4:false} - >> Patch(Foo, First(t1), {DisplayNameField2:"jupter"}) Errors: Error 6-9: Name isn't valid. 'Foo' isn't recognized.|Error 0-51: The function 'Patch' has some invalid arguments. @@ -129,23 +109,6 @@ Table({a:1,b:Blank()},{a:Blank(),b:"2"}) >> Set(t_an_bs, Table({a:1,b:If(false,"")},{a:Blank(),b:"2"})); Patch(t_an_bs, Last(t_an_bs), {a:2}); t_an_bs Table({a:1,b:Blank()},{a:2,b:"2"}) - -// Base record not found. If the record in its entirety is not matched then it should produce an error. ->> Collect(t1,{Field1:3,Field2:"phobos",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}); - Collect(t1,{Field1:2,Field2:"deimos",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}); - Patch(t1,{Field2:"deimos"},{Field3:DateTime(2030,2,1,0,0,0,0)}) -Error({Kind:ErrorKind.NotFound}) - ->> Collect(t1,{Field1:3,Field2:"phobos",Field3:DateTime(2024,2,1,0,0,0,0),Field4:false}); - Collect(t1,{Field1:2,Field2:"deimos",Field3:DateTime(2025,2,1,0,0,0,0),Field4:false}); - Patch(t1,{Field3:DateTime(2025,2,1,0,0,0,0)},{Field2:"pandora", Field1:55}) -Error({Kind:ErrorKind.NotFound}) - ->> Collect(t1, r2); - Patch(t1, {Field4:true}, {Field2:"phobos"}); - First(t1).DisplayNameField2 -Error({Kind:ErrorKind.NotFound}) - >> Patch(t1, {Field1:1}, {DisplayNameField2:"mars"}); First(t1).Field2 Error({Kind:ErrorKind.NotFound}) diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1Compat.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1Compat.txt index 21402dbe9b..0ff2d85a11 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1Compat.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1Compat.txt @@ -41,3 +41,40 @@ Errors: Error 13-143: The value passed to the 'Patch' function cannot be changed {Properties:{Moon:{Name:"Phobos"}}}, {Planet:"Jupter"}) Errors: Error 13-251: The value passed to the 'Patch' function cannot be changed. + + +>> Collect(t1, r2); + Patch(t1, Last(t1), {Field1:10}, {Field2:"Venus"}, {Field4:true}).Field1 +10 + +>> Collect(t1, r2); + Collect(t1, {Field1:3,Field2:"venus",Field3:DateTime(2030,1,1,0,0,0,0),Field4:true}); + Collect(t1, {Field1:4,Field2:"mars",Field3:DateTime(2031,1,1,0,0,0,0),Field4:false}); + Collect(t1, {Field1:5,Field2:"jupter",Field3:DateTime(2032,1,1,0,0,0,0),Field4:true}); + Collect(t1, {Field1:6,Field2:"saturn",Field3:DateTime(2033,1,1,0,0,0,0),Field4:false}); + Patch(t1, First(Filter(t1, Field1 > 4)), {Field2: "phobos"}); +{Field1:5,Field2:"phobos",Field3:DateTime(2032,1,1,0,0,0,0),Field4:true} + +>> Collect(t1, r2); + Collect(t1, {DisplayNameField1:3,Field2:"venus",Field3:DateTime(2030,1,1,0,0,0,0),DisplayNameField4:true}); + Collect(t1, {DisplayNameField1:4,Field2:"mars",Field3:DateTime(2031,1,1,0,0,0,0),DisplayNameField4:false}); + Collect(t1, {DisplayNameField1:5,Field2:"jupter",Field3:DateTime(2032,1,1,0,0,0,0),DisplayNameField4:true}); + Collect(t1, {DisplayNameField1:6,Field2:"saturn",Field3:DateTime(2033,1,1,0,0,0,0),DisplayNameField4:false}); + Patch(t1, Last(Filter(t1, Field4 = false)), {DisplayNameField2: "phobos"}); +{Field1:6,Field2:"phobos",Field3:DateTime(2033,1,1,0,0,0,0),Field4:false} + +// Base record not found. If the record in its entirety is not matched then it should produce an error. +>> Collect(t1,{Field1:3,Field2:"phobos",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}); + Collect(t1,{Field1:2,Field2:"deimos",Field3:DateTime(2022,2,1,0,0,0,0),Field4:false}); + Patch(t1,{Field2:"deimos"},{Field3:DateTime(2030,2,1,0,0,0,0)}) +Error({Kind:ErrorKind.NotFound}) + +>> Collect(t1,{Field1:3,Field2:"phobos",Field3:DateTime(2024,2,1,0,0,0,0),Field4:false}); + Collect(t1,{Field1:2,Field2:"deimos",Field3:DateTime(2025,2,1,0,0,0,0),Field4:false}); + Patch(t1,{Field3:DateTime(2025,2,1,0,0,0,0)},{Field2:"pandora", Field1:55}) +Error({Kind:ErrorKind.NotFound}) + +>> Collect(t1, r2); + Patch(t1, {Field4:true}, {Field2:"phobos"}); + First(t1).DisplayNameField2 +Error({Kind:ErrorKind.NotFound}) \ No newline at end of file diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1CompatDisabled.txt index 4dd4154700..b58a190dd8 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1CompatDisabled.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Patch_V1CompatDisabled.txt @@ -13,18 +13,6 @@ >> Patch(Table({Value:1}, If(false, {x:1, Value:2}, {Value:2, z:2}), {Value:3}), {Value:2}, {Value:11}) {Value:11} ->> Collect(t_empty, {Value:1}); Collect(t_empty, {Value:2}); Patch(t_empty, {Value:1}, If(false, {x:1, Value:2}, {Value:11, z:2})) -{Value:11} - ->> Collect(t_empty, {Value:1}); Collect(t_empty, {Value:2}); Patch(t_empty, If(false, {x:1, Value:2}, {Value:1, z:2}), {Value:11}) -{Value:11} - ->> Collect(t_empty, {Value:1}); Collect(t_empty, {Value:2}); Patch(t_empty, If(false, {x:1, Value:2}, {Value:1, z:2}), If(false, {x:1, Value:2}, {Value:11, z:2})) -{Value:11} - ->> Collect(t_empty, {Value:1}); Collect(t_empty, If(false, {x:1, Value:2}, {Value:2, z:2})); Collect(t_empty, {Value:3}); Patch(t_empty, {Value:2}, {Value:11}) -{Value:11} - // field22 is missing >> Patch( Table( diff --git a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Remove.txt b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Remove.txt index 98276cdd91..d7c577e2d4 100644 --- a/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Remove.txt +++ b/src/tests/Microsoft.PowerFx.Core.Tests/ExpressionTestCases/Remove.txt @@ -1,4 +1,4 @@ -#SETUP: EnableExpressionChaining,MutationFunctionsTestSetup +#SETUP: PowerFxV1CompatibilityRules,EnableExpressionChaining,MutationFunctionsTestSetup // Check MutationFunctionsTestSetup handler (PowerFxEvaluationTests.cs) for documentation. diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationFunctionsTests.cs b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationFunctionsTests.cs index 70a16670ee..e2474b557e 100644 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationFunctionsTests.cs +++ b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationFunctionsTests.cs @@ -382,6 +382,32 @@ public void SymbolTableEnableMutationFuntionsTest() // Mutation functions is listed. var checkEnabled = engine.Check(expr, symbolTable: symbolTableEnabled); Assert.Contains(checkEnabled.Symbols.Functions.FunctionNames, f => f == "Collect"); + } + + [Theory] + [InlineData("Collect(t, {Value:1})")] + [InlineData("Collect(t, 1)")] + [InlineData("ForAll(Sequence(5), Collect(t, {Value:ThisRecord.Value}))")] + [InlineData("Switch(2,1,Last(Collect(t,{Value:1})).Value,2,Last(Collect(t,{Value:2})).Value,3,Last(Collect(t,{Value:3})).Value)")] + [InlineData("IfError(1/0,Last(Collect(t,{Value:3})).Value)")] + public void CollectPFxV1Disabled(string expression) + { + var engine = new RecalcEngine(new PowerFxConfig(Features.None)); + var t = FormulaValue.NewTable(RecordType.Empty().Add(new NamedFormulaType("Value", FormulaType.Decimal))); + + engine.Config.SymbolTable.EnableMutationFunctions(); + engine.UpdateVariable("t", t); + + var check = engine.Check(expression, options: new ParserOptions() { AllowsSideEffects = true }); + + // Compilation will be successful, but the function will not be executed. + // This is because PA depends on the CheckType to determine if the function is valid. + Assert.True(check.IsSuccess); + + var evaluator = check.GetEvaluator(); + + // Runtime exception + Assert.Throws(() => evaluator.Eval()); } internal class FileObjectRecordValue : InMemoryRecordValue diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/AndOr_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/AndOr_V1CompatDisabled.txt index eb98a43650..37cb02f721 100644 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/AndOr_V1CompatDisabled.txt +++ b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/AndOr_V1CompatDisabled.txt @@ -6,7 +6,7 @@ Table({Value:false},{Value:true}) // AND ->> false && Last(Collect(t1, {Value:true})).Value;t1 +>> false && Clear(t1);t1 Table({Value:false},{Value:true}) >> 0.00;t1 @@ -30,7 +30,7 @@ Table({Value:false},{Value:true}) >> 0.03;t1 Table({Value:false},{Value:true}) ->> false And Last(Collect(t1, {Value:true})).Value;t1 +>> false And Clear(t1);t1 Table({Value:false},{Value:true}) >> 0.10;t1 @@ -54,7 +54,7 @@ Table({Value:false},{Value:true}) >> 0.13;t1 Table({Value:false},{Value:true}) ->> And(false, Last(Collect(t1, {Value:true})).Value);t1 +>> And(false, Clear(t1));t1 Table({Value:false},{Value:true}) >> 0.14;t1 @@ -79,7 +79,7 @@ Table({Value:false},{Value:true}) Table({Value:false},{Value:true}) // OR with true, none of these should execute ->> true || Last(Collect(t1, {Value:true})).Value +>> true || With({x:1},Clear(t1);true) true >> -1;t1 @@ -105,10 +105,13 @@ Table({Value:false},{Value:true}) Table({Value:false},{Value:true}) // OR with false, these should all execute ->> false || Last(Collect(t1, {Value:true})).Value +>> false || With({x:1},Clear(t1);true) true >> 1;t1 +Table() + +>> 0;Set( t1, [false,true,true] ) Table({Value:false},{Value:true},{Value:true}) >> false || Patch(t1, First(t1), {Value:true}).Value @@ -129,10 +132,13 @@ Table({Value:false},{Value:true}) >> 3.1;t1 Table({Value:false},{Value:true}) ->> Or(false, Last(Collect(t1, {Value:true})).Value) +>> Or(false, With({x:1},Clear(t1);true)) true >> 4;t1 +Table() + +>> 1;Set( t1, [false,true,true] ) Table({Value:false},{Value:true},{Value:true}) >> Or(false, Patch(t1, First(t1), {Value:true}).Value) diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Coalesce_CoalesceShortCircuitDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Coalesce_CoalesceShortCircuitDisabled.txt index 878415c0a3..3a6333f6f9 100644 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Coalesce_CoalesceShortCircuitDisabled.txt +++ b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Coalesce_CoalesceShortCircuitDisabled.txt @@ -5,42 +5,48 @@ >> Set( t1, [1,2] ) Table({Value:1},{Value:2}) ->> Coalesce(1,Last(Collect(t1,{Value:3})).Value) +>> Coalesce(1,Clear(t1)) 1 >> 1;t1 +Table() + +>> 1;Set( t1, [1,2,3] ) Table({Value:1},{Value:2},{Value:3}) ->> Coalesce(1,Blank(),Last(Collect(t1,{Value:3.1})).Value) +>> Coalesce(1,Blank(),Clear(t1)) 1 >> 1.1;t1 +Table() + +>> 2;Set( t1, [1,2,3,3.1] ) Table({Value:1},{Value:2},{Value:3},{Value:3.1}) >> Set( bn, If(1<0,1)) Blank() ->> Coalesce( bn, Last(Collect(t1,{Value:3.2})).Value ) -3.2 - ->> 2;t1 -Table({Value:1},{Value:2},{Value:3},{Value:3.1},{Value:3.2}) +>> Coalesce( bn, 1.1 ) +1.1 ->> Coalesce( bn, Last(Collect(t1,{Value:4})).Value, Last(Collect(t1,{Value:5})).Value ) -4 +>> Coalesce( bn, Remove(t1, First(t1));Last(t1).Value, Remove(t1, First(t1));Last(t1).Value ) +3.1 >> 3;t1 -Table({Value:1},{Value:2},{Value:3},{Value:3.1},{Value:3.2},{Value:4},{Value:5}) +Table({Value:3},{Value:3.1}) ->> Coalesce( bn, Blank(), Last(Collect(t1,{Value:5.1})).Value ) -5.1 +>> Coalesce( bn, Blank(), Remove(t1, First(t1));Last(t1).Value ) +3.1 >> 4;t1 -Table({Value:1},{Value:2},{Value:3},{Value:3.1},{Value:3.2},{Value:4},{Value:5},{Value:5.1}) +Table({Value:3.1}) + +>> 3;Set( t1, [1,2,3,3.1] ) +Table({Value:1},{Value:2},{Value:3},{Value:3.1}) ->> Coalesce( bn, Blank(), Last(Collect(t1,{Value:6})).Value, Last(Collect(t1,{Value:7})).Value ) -6 +>> Coalesce( bn, Blank(), Remove(t1, First(t1));First(t1).Value, Remove(t1, First(t1));Last(t1).Value ) +2 >> 5;t1 -Table({Value:1},{Value:2},{Value:3},{Value:3.1},{Value:3.2},{Value:4},{Value:5},{Value:5.1},{Value:6},{Value:7}) +Table({Value:3},{Value:3.1}) diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Collect.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Collect.txt index 98c150f492..d5bd6b09ea 100644 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Collect.txt +++ b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Collect.txt @@ -64,7 +64,7 @@ Errors: Error 16-29: The type of this argument 'Value' does not match the expect Table({Value:1},{Value:2},{Value:3}) >> Collect(temp1,{Value:"run time error"}).Value -Errors: Error 14-38: The type of this argument 'Value' does not match the expected type 'Decimal'. Found type 'Text'.|Error 0-39: The function 'Collect' has some invalid arguments.|Error 39-45: Name isn't valid. 'Value' isn't recognized. +Errors: Error 0-39: The function 'Collect' has some invalid arguments.|Error 14-38: The type of this argument 'Value' does not match the expected type 'Decimal'. Found type 'Text'.|Error 39-45: Deprecated use of '.'. Please use the 'ShowColumns' function instead. >> Set(partialT1, Table({a:1,b:1},{a:2,b:2})) Table({a:1,b:1},{a:2,b:2}) diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/DeepMutation_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/DeepMutation_V1CompatDisabled.txt deleted file mode 100644 index b0b96e5c84..0000000000 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/DeepMutation_V1CompatDisabled.txt +++ /dev/null @@ -1,412 +0,0 @@ -#SETUP: disable:PowerFxV1CompatibilityRules -// NESTED TABLES - PATCH - ->> Set( aa, [[1,2,3], [4,5,6]] ) -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> Set( ab, First(aa) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Patch( ab.Value, {Value:2}, {Value:9}) -{Value:9} - ->> ab -{Value:Table({Value:1},{Value:9},{Value:3})} - ->> Set( ac, Last(aa) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - ->> Patch( ac.Value, {Value:5}, {Value:8} ) -{Value:8} - ->> ac -{Value:Table({Value:4},{Value:8},{Value:6})} - ->> Set( ad, Index(aa,1) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Set( ae, Index(aa,2) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - ->> Patch( ad.Value, {Value:1}, {Value:10}) -{Value:10} - ->> Patch( ae.Value, {Value:6}, {Value:16}) -{Value:16} - ->> ad -{Value:Table({Value:10},{Value:2},{Value:3})} - ->> ae -{Value:Table({Value:4},{Value:5},{Value:16})} - ->> ab // confirm no changes -{Value:Table({Value:1},{Value:9},{Value:3})} - ->> ac // confirm no changes -{Value:Table({Value:4},{Value:8},{Value:6})} - ->> aa // confirm no changes -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - -// NESTED TABLES - COLLECT - ->> Set( ca, [[1,2,3], [4,5,6]] ) -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> Set( cb, First(ca) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Collect( cb.Value, {Value:9}) -Table({Value:1},{Value:2},{Value:3},{Value:9}) - ->> cb -{Value:Table({Value:1},{Value:2},{Value:3},{Value:9})} - ->> Set( cc, Last(ca) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - ->> Collect( cc.Value, {Value:8} ) -Table({Value:4},{Value:5},{Value:6},{Value:8}) - ->> cc -{Value:Table({Value:4},{Value:5},{Value:6},{Value:8})} - ->> Set( cd, Index(ca,1) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Set( ce, Index(ca,2) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - ->> Collect( cd.Value, {Value:10}) -Table({Value:1},{Value:2},{Value:3},{Value:10}) - ->> Collect( ce.Value, {Value:16}) -Table({Value:4},{Value:5},{Value:6},{Value:16}) - ->> cd -{Value:Table({Value:1},{Value:2},{Value:3},{Value:10})} - ->> ce -{Value:Table({Value:4},{Value:5},{Value:6},{Value:16})} - ->> cb // confirm no changes -{Value:Table({Value:1},{Value:2},{Value:3},{Value:9})} - ->> cc // confirm no changes -{Value:Table({Value:4},{Value:5},{Value:6},{Value:8})} - ->> ca // confirm no changes -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - -// NESTED TABLES - CLEARCOLLECT - ->> Set( cca, [[1,2,3], [4,5,6]] ) -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> Set( ccb, First(cca) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> ClearCollect( ccb.Value, {Value:9}) -{Value:9} - ->> ccb -{Value:Table({Value:9})} - ->> Set( ccc, Last(ca) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - ->> ClearCollect( ccc.Value, {Value:8} ) -{Value:8} - ->> ccc -{Value:Table({Value:8})} - ->> Set( ccd, Index(ca,1) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Set( cce, Index(ca,2) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - ->> ClearCollect( ccd.Value, {Value:10}) -{Value:10} - ->> ClearCollect( cce.Value, {Value:16}) -{Value:16} - ->> ccd -{Value:Table({Value:10})} - ->> cce -{Value:Table({Value:16})} - ->> ccb // confirm no changes -{Value:Table({Value:9})} - ->> ccc // confirm no changes -{Value:Table({Value:8})} - ->> cca // confirm no changes -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - -// NESTED TABLES - CLEAR - ->> Set( cla, [[1,2,3], [4,5,6]] ) -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> Set( clb, First(cla) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - -// ; true on the end so that we get the same result with and without V1Compat ->> Clear( clb.Value ); true -true - ->> clb -{Value:Table()} - ->> Set( clc, Last(cla) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - -// ; true on the end so that we get the same result with and without V1Compat ->> Clear( clc.Value ); true -true - ->> clc -{Value:Table()} - ->> Collect( clb.Value, {Value:91}) -Table({Value:91}) - ->> Collect( clc.Value, {Value:81}) -Table({Value:81}) - ->> Set( cld, Index(ca,1) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Set( cle, Index(ca,2) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - -// ; true on the end so that we get the same result with and without V1Compat ->> Clear( cld.Value); true -true - -// ; true on the end so that we get the same result with and without V1Compat ->> Clear( cle.Value); true -true - ->> cld -{Value:Table()} - ->> cle -{Value:Table()} - ->> clb // confirm no changes -{Value:Table({Value:91})} - ->> clc // confirm no changes -{Value:Table({Value:81})} - ->> cla // confirm no changes -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - -// NESTED TABLES - REMOVE - ->> Set( ra, [[1,2,3], [4,5,6]] ) -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> Set( rb, First(ra) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove( rb.Value, {Value:2} ); true -true - ->> rb -{Value:Table({Value:1},{Value:3})} - ->> Set( rc, Last(ra) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove( rc.Value, {Value:4} ); true -true - ->> rc -{Value:Table({Value:5},{Value:6})} - ->> Set( rd, Index(ra,1) ) -{Value:Table({Value:1},{Value:2},{Value:3})} - ->> Set( re, Index(ra,2) ) -{Value:Table({Value:4},{Value:5},{Value:6})} - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove( rd.Value, {Value:3}); true -true - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove( re.Value, {Value:4}); true -true - ->> rd -{Value:Table({Value:1},{Value:2})} - ->> re -{Value:Table({Value:5},{Value:6})} - ->> rb // confirm no changes -{Value:Table({Value:1},{Value:3})} - ->> rc // confirm no changes -{Value:Table({Value:5},{Value:6})} - ->> ra // confirm no changes -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - -// DEEP NESTING IN RECORDS - PATCH - ->> Set( ba, {a: {b: {c: {d: [1,2,3]} } } } ) -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:3})}}}} - ->> Set( bb, ba.a.b ) -{c:{d:Table({Value:1},{Value:2},{Value:3})}} - ->> Set( bc, ba.a.b.c ) -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Set( bd, bb.c ) -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Patch( ba.a.b.c.d, {Value:3}, {Value:9} ) -{Value:9} - ->> ba -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:9})}}}} - ->> bb -{c:{d:Table({Value:1},{Value:2},{Value:3})}} - ->> bc -{d:Table({Value:1},{Value:2},{Value:3})} - ->> bd -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Patch( bb.c.d, {Value:2}, {Value:8} ) -{Value:8} - ->> ba // after bb -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:9})}}}} - ->> bb // after bb -{c:{d:Table({Value:1},{Value:8},{Value:3})}} - ->> bc // after bb -{d:Table({Value:1},{Value:2},{Value:3})} - ->> bd // after bb -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Patch( bc.d, {Value:1}, {Value:7}) -{Value:7} - ->> ba // after bc -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:9})}}}} - ->> bb // after bc -{c:{d:Table({Value:1},{Value:8},{Value:3})}} - ->> bc // after bc -{d:Table({Value:7},{Value:2},{Value:3})} - ->> bd // after bc -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Patch( bd.d, { Value: 2}, {Value: 11 }) -{Value:11} - ->> ba // after bd -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:9})}}}} - ->> bb // after bd -{c:{d:Table({Value:1},{Value:8},{Value:3})}} - ->> bc // after bd -{d:Table({Value:7},{Value:2},{Value:3})} - ->> bd // after bd -{d:Table({Value:1},{Value:11},{Value:3})} - -// DEEP NESTING IN RECORDS - COLLECT - ->> Set( dba, {a: {b: {c: {d: [1,2,3]} } } } ) -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:3})}}}} - ->> Set( dbb, dba.a.b ) -{c:{d:Table({Value:1},{Value:2},{Value:3})}} - ->> Set( dbc, dba.a.b.c ) -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Set( dbd, dbb.c ) -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Collect( dba.a.b.c.d, {Value:9} ) -Table({Value:1},{Value:2},{Value:3},{Value:9}) - ->> dba -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:9})}}}} - ->> dbb -{c:{d:Table({Value:1},{Value:2},{Value:3})}} - ->> dbc -{d:Table({Value:1},{Value:2},{Value:3})} - ->> dbd -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Collect( dbb.c.d, {Value:8} ) -Table({Value:1},{Value:2},{Value:3},{Value:8}) - ->> dba // after dbb -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:9})}}}} - ->> dbb // after dbb -{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:8})}} - ->> dbc // after dbb -{d:Table({Value:1},{Value:2},{Value:3})} - ->> dbd // after dbb -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Collect( dbc.d, {Value:7}) -Table({Value:1},{Value:2},{Value:3},{Value:7}) - ->> dba // after dbc -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:9})}}}} - ->> dbb // after dbc -{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:8})}} - ->> dbc // after dbc -{d:Table({Value:1},{Value:2},{Value:3},{Value:7})} - ->> dbd // after dbc -{d:Table({Value:1},{Value:2},{Value:3})} - ->> Collect( dbd.d, {Value: 11}) -Table({Value:1},{Value:2},{Value:3},{Value:11}) - ->> dba // after dbd -{a:{b:{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:9})}}}} - ->> dbb // after dbd -{c:{d:Table({Value:1},{Value:2},{Value:3},{Value:8})}} - ->> dbc // after dbd -{d:Table({Value:1},{Value:2},{Value:3},{Value:7})} - ->> dbd // after dbd -{d:Table({Value:1},{Value:2},{Value:3},{Value:11})} diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/ForAllMutate_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/ForAllMutate_V1CompatDisabled.txt deleted file mode 100644 index ddcc241ba7..0000000000 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/ForAllMutate_V1CompatDisabled.txt +++ /dev/null @@ -1,107 +0,0 @@ -#SETUP: disable:PowerFxV1CompatibilityRules -// Test mutations on a collection from ForAll() - -// These are all verified in Power Apps -// - ->> Set(t, Sequence(4)) -Table({Value:1},{Value:2},{Value:3},{Value:4}) - ->> Collect(t, { Value : 99}); Concat(t, Value) -"123499" - ->> Set(t, ForAll(Sequence(4), Value*10)) -Table({Value:10},{Value:20},{Value:30},{Value:40}) - ->> Collect(t, { Value : 99}); Concat(t, Value) // After t was changed -"1020304099" - -// Initializing t2 ->> Set(t2, [1]) -Table({Value:1}) - ->> With({t: Sequence(5)}, Set(t2, ForAll(t, Value * 2))); t2 -Table({Value:2},{Value:4},{Value:6},{Value:8},{Value:10}) - -// Inner sequence is unchaged ->> With( { t : Sequence(5)}, - Collect(t2, { Value : 99 }); - Concat(t, Value) & "," & Concat(t2, Value) - ) -"12345,24681099" - -// short circuiting shouldn't execute any loops for a blank or empty table - ->> Set(t3,If(1<0,[1,2,3])) -Blank() - ->> ForAll(t3,Patch(t3,ThisRecord,{Value:4})) -Blank() - ->> 1;t3 -Blank() - -// interpretation of an empty table - ->> Set(t4,[1]) -Table({Value:1}) - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove(t4,First(t4)); true -true - ->> 1;t4 -Table() - -// Should do nothing as t4 is empty ->> ForAll(t4,Patch(t4,ThisRecord,{Value:4})) -Table() - ->> 2;t4 -Table() - ->> Set(t5,[1]) -Table({Value:1}) - -// ForAll shouldn't execute the collect, even once ->> ForAll(t4,Collect(t5,{Value:9.1})) -Table() - -// With shouldn't execute the collect, even once ->> With(First(t4),Collect(t5,{Value:9.2})) -Blank() - -// interpretation of one record - ->> 1;t5 -Table({Value:1}) - ->> Collect(t4,{Value:1}) -Table({Value:1}) - -// ForAll should execute the collect, exactly once ->> ForAll(t4,Collect(t5,{Value:8.1})) -Table({Value:Table({Value:1},{Value:8.1})}) - -// With shouldn execute the collect, exactly once ->> With(First(t4),Collect(t5,{Value:8.2})) -Table({Value:1},{Value:8.1},{Value:8.2}) - ->> 2;t5 -Table({Value:1},{Value:8.1},{Value:8.2}) - -// interpretation of a blank table - ->> Set( t4, Blank() ) -Blank() - -// ForAll shouldn't execute the collect, even once ->> ForAll(t4,Collect(t5,{Value:7.1})) -Blank() - -// With shouldn't execute the collect, even once ->> With(First(t4),Collect(t5,{Value:7.2})) -Blank() - ->> 3;t5 -Table({Value:1},{Value:8.1},{Value:8.2}) diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/IfError_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/IfError_V1CompatDisabled.txt deleted file mode 100644 index d36193ffd2..0000000000 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/IfError_V1CompatDisabled.txt +++ /dev/null @@ -1,47 +0,0 @@ -#SETUP: disable:PowerFxV1CompatibilityRules -// Cases to test how shortcut verification work along with behavior functions - ->> Set( t1, [1,2] ) -Table({Value:1},{Value:2}) - ->> IfError(1,Last(Collect(t1,{Value:3})).Value) -1 - ->> 1;t1 -Table({Value:1},{Value:2}) - ->> IfError(1/0,Last(Collect(t1,{Value:3})).Value) -3 - ->> 2;t1 -Table({Value:1},{Value:2},{Value:3}) - ->> IfError(1/0,Last(Collect(t1,{Value:4})).Value,1/0,Last(Collect(t1,{Value:5})).Value) -4 - ->> 3;t1 -Table({Value:1},{Value:2},{Value:3},{Value:4}) - ->> IfError(1/0,Last(Collect(t1,{Value:5})).Value,1/0,Last(Collect(t1,{Value:6})).Value,Last(Collect(t1,{Value:7})).Value) -5 - ->> 4;t1 -Table({Value:1},{Value:2},{Value:3},{Value:4},{Value:5}) - ->> IfError(1,Last(Collect(t1,{Value:5})).Value,1/0,Last(Collect(t1,{Value:6})).Value,Last(Collect(t1,{Value:7})).Value) -6 - ->> 5;t1 -Table({Value:1},{Value:2},{Value:3},{Value:4},{Value:5},{Value:6}) - ->> IfError(1,Last(Collect(t1,{Value:5})).Value,2,Last(Collect(t1,{Value:6})).Value,Last(Collect(t1,{Value:7})).Value) -7 - ->> 6;t1 -Table({Value:1},{Value:2},{Value:3},{Value:4},{Value:5},{Value:6},{Value:7}) - ->> IfError(1,Last(Collect(t1,{Value:5})).Value,2,Last(Collect(t1,{Value:6})).Value) -2 - ->> 7;t1 -Table({Value:1},{Value:2},{Value:3},{Value:4},{Value:5},{Value:6},{Value:7}) diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Set_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Set_V1CompatDisabled.txt deleted file mode 100644 index 73049e93f6..0000000000 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Set_V1CompatDisabled.txt +++ /dev/null @@ -1,273 +0,0 @@ -#SETUP: disable:PowerFxV1CompatibilityRules - -// Tests for Set/Clear/Patch/Remove with Copy-on-Write semantics - -// TABLE MUTATION - ->> Set( a, [1,2,3] ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( b, a ) -Table({Value:1},{Value:2},{Value:3}) - ->> Patch( a, {Value:2}, {Value:9} ) -{Value:9} - ->> a -Table({Value:1},{Value:9},{Value:3}) - ->> b -Table({Value:1},{Value:2},{Value:3}) - -// TABLE APPEND - ->> Set( aa, [1,2,3] ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( ab, aa ) -Table({Value:1},{Value:2},{Value:3}) - ->> Collect( ab, {Value:4} ) -Table({Value:1},{Value:2},{Value:3},{Value:4}) - ->> aa -Table({Value:1},{Value:2},{Value:3}) - ->> ab -Table({Value:1},{Value:2},{Value:3},{Value:4}) - ->> Collect( aa, {Value:5} ) -Table({Value:1},{Value:2},{Value:3},{Value:5}) - ->> aa // again -Table({Value:1},{Value:2},{Value:3},{Value:5}) - ->> ab // again -Table({Value:1},{Value:2},{Value:3},{Value:4}) - -// TABLE WITHIN RECORD - ->> Set( ba, [ [1,2,3], [4,5,6] ]) -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> Set( bb, Last(ba).Value ) -Table({Value:4},{Value:5},{Value:6}) - ->> Patch( bb, {Value:4}, {Value:8} ) -{Value:8} - ->> ba -Table({Value:Table({Value:1},{Value:2},{Value:3})},{Value:Table({Value:4},{Value:5},{Value:6})}) - ->> bb -Table({Value:8},{Value:5},{Value:6}) - -// TABLE REMOVE - ->> Set( ca, [1,2,3] ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( cb, ca ) -Table({Value:1},{Value:2},{Value:3}) - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove( cb, {Value:2} ); true -true - ->> ca // again -Table({Value:1},{Value:2},{Value:3}) - ->> cb // again -Table({Value:1},{Value:3}) - -// ; true on the end so that we get the same result with and without V1Compat ->> Remove( ca, {Value:1} ); true -true - ->> ca // again 2 -Table({Value:2},{Value:3}) - ->> cb // again 2 -Table({Value:1},{Value:3}) - -// TABLE CLEAR - ->> Set( da, [1,2,3] ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( db, da ) -Table({Value:1},{Value:2},{Value:3}) - ->> da -Table({Value:1},{Value:2},{Value:3}) - ->> db -Table({Value:1},{Value:2},{Value:3}) - -// ; true on the end so that we get the same result with and without V1Compat ->> Clear( da ); true -true - ->> da // again -Table() - ->> db // again -Table({Value:1},{Value:2},{Value:3}) - -// LOTS OF COPIES - ->> Set( ea, [1,2,3] ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( eb, ea ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( ec, eb ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( ed, ec ) -Table({Value:1},{Value:2},{Value:3}) - ->> Patch( ec, {Value:3}, {Value:7} ) -{Value:7} - ->> ea -Table({Value:1},{Value:2},{Value:3}) - ->> eb -Table({Value:1},{Value:2},{Value:3}) - ->> ec -Table({Value:1},{Value:2},{Value:7}) - ->> ed -Table({Value:1},{Value:2},{Value:3}) - ->> Collect( eb, {Value:9} ) -Table({Value:1},{Value:2},{Value:3},{Value:9}) - ->> ea // again -Table({Value:1},{Value:2},{Value:3}) - ->> eb // again -Table({Value:1},{Value:2},{Value:3},{Value:9}) - ->> ec // again -Table({Value:1},{Value:2},{Value:7}) - ->> ed // again -Table({Value:1},{Value:2},{Value:3}) - -// ; true on the end so that we get the same result with and without V1Compat ->> Clear( ea ); true -true - ->> ea // again 2 -Table() - ->> eb // again 2 -Table({Value:1},{Value:2},{Value:3},{Value:9}) - ->> ec // again 2 -Table({Value:1},{Value:2},{Value:7}) - ->> ed // again 2 -Table({Value:1},{Value:2},{Value:3}) - -// MORE NESTED TABLES - ->> Set( fa, Table( { a:[1,2,3], b:[4,5,6], c:"hi", d:true}, { a:[10,20,30], b:[40,50,60], c:"bye", d:false} ) ) -Table({a:Table({Value:1},{Value:2},{Value:3}),b:Table({Value:4},{Value:5},{Value:6}),c:"hi",d:true},{a:Table({Value:10},{Value:20},{Value:30}),b:Table({Value:40},{Value:50},{Value:60}),c:"bye",d:false}) - ->> Set( fb, fa ) -Table({a:Table({Value:1},{Value:2},{Value:3}),b:Table({Value:4},{Value:5},{Value:6}),c:"hi",d:true},{a:Table({Value:10},{Value:20},{Value:30}),b:Table({Value:40},{Value:50},{Value:60}),c:"bye",d:false}) - ->> Set( fc, Index(fa, 2).b ) -Table({Value:40},{Value:50},{Value:60}) - ->> Patch( fc, {Value:50}, {Value:1000} ) -{Value:1000} - ->> fa -Table({a:Table({Value:1},{Value:2},{Value:3}),b:Table({Value:4},{Value:5},{Value:6}),c:"hi",d:true},{a:Table({Value:10},{Value:20},{Value:30}),b:Table({Value:40},{Value:50},{Value:60}),c:"bye",d:false}) - ->> fb -Table({a:Table({Value:1},{Value:2},{Value:3}),b:Table({Value:4},{Value:5},{Value:6}),c:"hi",d:true},{a:Table({Value:10},{Value:20},{Value:30}),b:Table({Value:40},{Value:50},{Value:60}),c:"bye",d:false}) - ->> fc -Table({Value:40},{Value:1000},{Value:60}) - -// NESTED TABLES DEEPLY IN RECORDS - ->> Set( ga, { a: { b: { c: [1,2,3] }}}) -{a:{b:{c:Table({Value:1},{Value:2},{Value:3})}}} - ->> Set( gb, ga.a.b.c ) -Table({Value:1},{Value:2},{Value:3}) - ->> Patch( gb, First(gb), {Value:9} ) -{Value:9} - ->> ga -{a:{b:{c:Table({Value:1},{Value:2},{Value:3})}}} - ->> gb -Table({Value:9},{Value:2},{Value:3}) - ->> Set( gc, ga.a ) -{b:{c:Table({Value:1},{Value:2},{Value:3})}} - ->> Set( gd, gc.b ) -{c:Table({Value:1},{Value:2},{Value:3})} - ->> Set( ge, gd.c ) -Table({Value:1},{Value:2},{Value:3}) - ->> Collect( ge, {Value:88} ) -Table({Value:1},{Value:2},{Value:3},{Value:88}) - ->> ga // again -{a:{b:{c:Table({Value:1},{Value:2},{Value:3})}}} - ->> gb // again -Table({Value:9},{Value:2},{Value:3}) - ->> gc // again -{b:{c:Table({Value:1},{Value:2},{Value:3})}} - ->> gd // again -{c:Table({Value:1},{Value:2},{Value:3})} - ->> ge // again -Table({Value:1},{Value:2},{Value:3},{Value:88}) - -// SET RECORD FROM ANOTHER TABLE - ->> Set( ha, [1,2,3] ) -Table({Value:1},{Value:2},{Value:3}) - ->> Set( hb, Table(Index(ha,2),Last(ha),First(ha))) -Table({Value:2},{Value:3},{Value:1}) - ->> ha -Table({Value:1},{Value:2},{Value:3}) - ->> hb -Table({Value:2},{Value:3},{Value:1}) - ->> Patch( ha, First(ha), {Value:5}) -{Value:5} - ->> Patch( ha, Index(ha,2), {Value:6}) -{Value:6} - ->> Patch( ha, Last(ha), {Value:7}) -{Value:7} - ->> ha // again -Table({Value:5},{Value:6},{Value:7}) - ->> hb // again -Table({Value:2},{Value:3},{Value:1}) - - diff --git a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Switch_V1CompatDisabled.txt b/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Switch_V1CompatDisabled.txt deleted file mode 100644 index 509b114ec4..0000000000 --- a/src/tests/Microsoft.PowerFx.Interpreter.Tests/MutationScripts/Switch_V1CompatDisabled.txt +++ /dev/null @@ -1,54 +0,0 @@ -#SETUP: disable:PowerFxV1CompatibilityRules - -// Cases to test how shortcut verification work along with behavior functions - ->> Set( t1, [0,1] ) -Table({Value:0},{Value:1}) - ->> Switch(2,1,Last(Collect(t1,{Value:1})).Value,2,Last(Collect(t1,{Value:2})).Value,3,Last(Collect(t1,{Value:3})).Value) -2 - ->> 1;t1 -Table({Value:0},{Value:1},{Value:2}) - ->> Switch(3, - 1,Last(Collect(t1,{Value:1})).Value, - 2,Last(Collect(t1,{Value:2})).Value, - 3,Last(Collect(t1,{Value:3})).Value, - Last(Collect(t1,{Value:4})).Value) -3 - ->> 2;t1 -Table({Value:0},{Value:1},{Value:2},{Value:3}) - ->> Switch(1, - 1,Last(Collect(t1,{Value:4})).Value, - 2,Last(Collect(t1,{Value:6})).Value, - 3,Last(Collect(t1,{Value:7})).Value, - Last(Collect(t1,{Value:8})).Value) -4 - ->> 3;t1 -Table({Value:0},{Value:1},{Value:2},{Value:3},{Value:4}) - ->> Switch(6, - Last(Collect(t1,{Value:5})).Value,1, - Last(Collect(t1,{Value:6})).Value,12, - 2,Last(Collect(t1,{Value:7})).Value, - Last(Collect(t1,{Value:8})).Value) -12 - ->> 4;t1 -Table({Value:0},{Value:1},{Value:2},{Value:3},{Value:4},{Value:5},{Value:6}) - ->> Switch(9, - Last(Collect(t1,{Value:7})).Value,Last(Collect(t1,{Value:20})).Value, - Last(Collect(t1,{Value:8})).Value,2, - 6,8, - Last(Collect(t1,{Value:9})).Value,Last(Collect(t1,{Value:10})).Value, - Last(Collect(t1,{Value:30})).Value) -10 - ->> 5;t1 -Table({Value:0},{Value:1},{Value:2},{Value:3},{Value:4},{Value:5},{Value:6},{Value:7},{Value:8},{Value:9},{Value:10}) -