public void AddCustomFunction_CannotAddFunctionWhichAlreadyExistsAsBuiltInWithSameFullSignature_AddAsOverload() { try { // Add exisiting with 'addAsOverload' 'true' Action addCustomFunction = () => CustomUriFunctions.AddCustomUriFunction(BUILT_IN_GEODISTANCE_FUNCTION_NAME, GEO_DISTANCE_BUILTIN_FUNCTION_SIGNATURE); // Assert addCustomFunction.Throws <ODataException>(Strings.CustomUriFunctions_AddCustomUriFunction_BuiltInExistsFullSignature(BUILT_IN_GEODISTANCE_FUNCTION_NAME)); } finally { // Clean from CustomUriFunctions cache CustomUriFunctions.RemoveCustomUriFunction(BUILT_IN_GEODISTANCE_FUNCTION_NAME); } }
/// <summary> /// This is a shortcut of adding the custom FunctionSignature through 'CustomUriFunctions' class and /// binding the function name to it's MethodInfo through 'UriFunctionsBinder' class. /// See these classes documentations. /// In case of an exception, both operations(adding the signature and binding the function) will be undone. /// </summary> /// <param name="functionName">The uri function name that appears in the OData request uri.</param> /// <param name="functionSignature">The new custom function signature.</param> /// <param name="methodInfo">The MethodInfo to bind the given function name.</param> /// <exception cref="Exception">Any exception thrown by 'CustomUriFunctions.AddCustomUriFunction' and 'UriFunctionBinder.BindUriFunctionName' methods.</exception> public static void AddCustomUriFunction(string functionName, FunctionSignatureWithReturnType functionSignature, MethodInfo methodInfo) { try { // Add to OData.Libs function signature CustomUriFunctions.AddCustomUriFunction(functionName, functionSignature); // Bind the method to it's MethoInfo UriFunctionsBinder.BindUriFunctionName(functionName, methodInfo); } catch { // Clear in case of excpetion RemoveCustomUriFunction(functionName, functionSignature, methodInfo); throw; } }
public void RemoveCustomFunction_ShouldRemoveAnExistingFunction_ByName() { string customFunctionName = "my.ExistingCustomFunction"; // Prepare FunctionSignatureWithReturnType existingCustomFunctionSignature = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetDouble(false), EdmCoreModel.Instance.GetBoolean(false)); CustomUriFunctions.AddCustomUriFunction(customFunctionName, existingCustomFunctionSignature); Assert.True(GetCustomFunctionSignaturesOrNull(customFunctionName)[0].Equals(existingCustomFunctionSignature)); // Test bool isRemoveSucceeded = CustomUriFunctions.RemoveCustomUriFunction(customFunctionName); // Assert Assert.True(isRemoveSucceeded); Assert.Null(GetCustomFunctionSignaturesOrNull(customFunctionName)); }
static EdmModelExtensions() { CustomUriFunctions.AddCustomUriFunction("empty", new FunctionSignatureWithReturnType( EdmCoreModel.Instance.GetBoolean(false), EdmCoreModel.Instance.GetUntyped())); CustomUriFunctions.AddCustomUriFunction("exists", new FunctionSignatureWithReturnType( EdmCoreModel.Instance.GetBoolean(false), EdmCoreModel.Instance.GetUntyped())); CustomUriFunctions.AddCustomUriFunction("distanceto", new FunctionSignatureWithReturnType( EdmCoreModel.Instance.GetDouble(false), EdmCoreModel.Instance.GetString(true), EdmCoreModel.Instance.GetInt32(true), EdmCoreModel.Instance.GetInt32(true))); }
public void ParseWithCustomUriFunction() { try { FunctionSignatureWithReturnType myStringFunction = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetBoolean(true), EdmCoreModel.Instance.GetString(true), EdmCoreModel.Instance.GetString(true)); // Add a custom uri function CustomUriFunctions.AddCustomUriFunction("mystringfunction", myStringFunction); var fullUri = new Uri("http://www.odata.com/OData/People" + "?$filter=mystringfunction(Name, 'BlaBla')"); ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData/"), fullUri); var startsWithArgs = parser.ParseFilter().Expression.ShouldBeSingleValueFunctionCallQueryNode("mystringfunction").Parameters.ToList(); startsWithArgs[0].ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp()); startsWithArgs[1].ShouldBeConstantQueryNode("BlaBla"); } finally { Assert.True(CustomUriFunctions.RemoveCustomUriFunction("mystringfunction")); } }
public void RemoveCustomFunction_RemoveFunctionWithSameNameAndSignature_OtherOverloadsExists() { string customFunctionName = "my.ExistingCustomFunction"; try { // Prepare FunctionSignatureWithReturnType existingCustomFunctionSignature = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetDouble(false), EdmCoreModel.Instance.GetBoolean(false)); CustomUriFunctions.AddCustomUriFunction(customFunctionName, existingCustomFunctionSignature); FunctionSignatureWithReturnType existingCustomFunctionSignatureTwo = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetBoolean(false), EdmCoreModel.Instance.GetDate(false)); CustomUriFunctions.AddCustomUriFunction(customFunctionName, existingCustomFunctionSignatureTwo); // Validate that the two overloads as GetCustomFunctionSignaturesOrNull(customFunctionName). All(funcSignature => funcSignature.Equals(existingCustomFunctionSignature) || funcSignature.Equals(existingCustomFunctionSignatureTwo)). Should().BeTrue(); // Remove the first overload, second overload should not be removed bool isRemoveSucceeded = CustomUriFunctions.RemoveCustomUriFunction(customFunctionName, existingCustomFunctionSignature); // Assert isRemoveSucceeded.Should().BeTrue(); FunctionSignatureWithReturnType[] overloads = GetCustomFunctionSignaturesOrNull(customFunctionName); overloads.Length.Should().Be(1); overloads[0].Should().Be(existingCustomFunctionSignatureTwo); } finally { // Clean up cache CustomUriFunctions.RemoveCustomUriFunction(customFunctionName); } }
public void ParseWithCustomUriFunction_AddAsOverloadToBuiltIn() { FunctionSignatureWithReturnType customStartWithFunctionSignature = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetBoolean(true), EdmCoreModel.Instance.GetString(true), EdmCoreModel.Instance.GetInt32(true)); try { // Add with override 'true' CustomUriFunctions.AddCustomUriFunction("startswith", customStartWithFunctionSignature); var fullUri = new Uri("http://www.odata.com/OData/People" + "?$filter=startswith(Name, 66)"); ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData/"), fullUri); var startsWithArgs = parser.ParseFilter().Expression.ShouldBeSingleValueFunctionCallQueryNode("startswith").Parameters.ToList(); startsWithArgs[0].ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp()); startsWithArgs[1].ShouldBeConstantQueryNode(66); } finally { Assert.True(CustomUriFunctions.RemoveCustomUriFunction("startswith")); } }
public void ParseWithExactMatchCustomUriFunction_EnableCaseInsensitive_ShouldWorkForMultipleEquivalentArgumentsMatches() { string lowerCaseName = "myfunction"; string upperCaseName = lowerCaseName.ToUpper(); FunctionSignatureWithReturnType myStringFunction = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetBoolean(true), EdmCoreModel.Instance.GetString(true), EdmCoreModel.Instance.GetString(true)); // Add two customer uri functions with same argument types, with names different in cases. CustomUriFunctions.AddCustomUriFunction(lowerCaseName, myStringFunction); CustomUriFunctions.AddCustomUriFunction(upperCaseName, myStringFunction); string rootUri = "http://www.odata.com/OData/"; string uriTemplate = rootUri + "People?$filter={0}(Name,'BlaBla')"; try { foreach (string functionName in new string[] { lowerCaseName, upperCaseName }) { // Uri with case-sensitive function names referring to equivalent-argument-typed functions, // should work for resolver with case insensitive enabled. var fullUri = new Uri(string.Format(uriTemplate, functionName)); ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri(rootUri), fullUri); parser.Resolver.EnableCaseInsensitive = true; var startsWithArgs = parser.ParseFilter().Expression.ShouldBeSingleValueFunctionCallQueryNode(functionName) .Parameters.ToList(); startsWithArgs[0].ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp()); startsWithArgs[1].ShouldBeConstantQueryNode("BlaBla"); } } finally { Assert.True(CustomUriFunctions.RemoveCustomUriFunction(lowerCaseName)); Assert.True(CustomUriFunctions.RemoveCustomUriFunction(upperCaseName)); } }