diff --git a/test/UnitTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/FilterAndOrderByFunctionalTests.cs b/test/UnitTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/FilterAndOrderByFunctionalTests.cs index f8268402b5..bdd29bc1ae 100644 --- a/test/UnitTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/FilterAndOrderByFunctionalTests.cs +++ b/test/UnitTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/FilterAndOrderByFunctionalTests.cs @@ -2653,6 +2653,37 @@ public void FilterWithInOperationWithEnumsInvalidMemberNames_ThrowsIsNotValidEnu action.Throws(Error.Format(SRResources.Binder_IsNotValidEnumConstant, expectedExceptionParameter)); } + [Fact] + public void MatchesPatternInFilterWithTheReturnType() + { + // Arrange & Act - Filter people whose names match capitalized pattern + var filterClause = ParseFilter("matchesPattern(Name, '^[A-Z][a-z]+$')", HardCodedTestModel.TestModel, HardCodedTestModel.GetPersonType(), HardCodedTestModel.GetPeopleSet()); + + // Assert + var functionCallNode = filterClause.Expression.ShouldBeSingleValueFunctionCallQueryNode("matchesPattern"); + Assert.Equal(2, functionCallNode.Parameters.Count()); + Assert.True(functionCallNode.TypeReference.IsBoolean()); + + // Verify first parameter is the Name property + functionCallNode.Parameters.ElementAt(0) + .ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp()); + + // Verify second parameter is the regex pattern + functionCallNode.Parameters.ElementAt(1).ShouldBeConstantQueryNode("^[A-Z][a-z]+$"); + } + + [Fact] + public void MatchesPatternInFilterWithBooleanComparison() + { + // Arrange & Act - Use matchesPattern in boolean expression + var filterClause = ParseFilter("matchesPattern(Name, '[0-9]+') eq true", HardCodedTestModel.TestModel, HardCodedTestModel.GetPersonType(), HardCodedTestModel.GetPeopleSet()); + + // Assert + var binaryOp = filterClause.Expression.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Equal); + binaryOp.Left.ShouldBeSingleValueFunctionCallQueryNode("matchesPattern"); + binaryOp.Right.ShouldBeConstantQueryNode(true); + } + [Fact] public void FilterWithInOperationWithAny() { diff --git a/test/UnitTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs b/test/UnitTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs index cf8864fea9..714c9bc323 100644 --- a/test/UnitTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs +++ b/test/UnitTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs @@ -1297,6 +1297,32 @@ public void CannotCallFunctionInOpenTypeSpace() bindOpenFunction.Throws(Error.Format(SRResources.FunctionCallBinder_CallingFunctionOnOpenProperty, "Fully.Qualified.Namespace.FindMyOwner")); } + [Fact] + public void MatchesPatternFunctionBindsCorrectly() + { + // Arrange + var arguments = new List() + { + new EndPathToken("Name", new RangeVariableToken(ExpressionConstants.It)), + new LiteralToken(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$") + }; + var token = new FunctionCallToken("matchesPattern", arguments); + + // Act + var result = functionCallBinder.BindFunctionCall(token); + + // Assert + var functionCallNode = result.ShouldBeSingleValueFunctionCallQueryNode("matchesPattern", EdmCoreModel.Instance.GetBoolean(false)); + Assert.Equal(2, functionCallNode.Parameters.Count()); + Assert.True(functionCallNode.TypeReference.IsBoolean()); + + // Verify first parameter is the Name property + functionCallNode.Parameters.ElementAt(0).ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp()); + + // Verify second parameter is the regex pattern + functionCallNode.Parameters.ElementAt(1).ShouldBeConstantQueryNode(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"); + } + [Fact] public void GetUriFunction_CombineCustomFunctionsAndBuiltInFunctions() {