From affb13afb36d05ceb96d9d267e32b64bea8fb307 Mon Sep 17 00:00:00 2001 From: Paul Ward Date: Mon, 13 Mar 2023 20:13:44 +0000 Subject: [PATCH 01/19] CODE RUB: Change Method name Execute to ApplyExpression --- OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs | 2 +- OData.Neo.Core/Brokers/Expressions/IExpressionBroker.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs b/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs index d62b7f4..e9c8341 100644 --- a/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs +++ b/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs @@ -32,7 +32,7 @@ await CSharpScript.RunAsync( return state.ReturnValue; } - public IQueryable Execute(IQueryable sources, Expression expression) + public IQueryable ApplyExpression(IQueryable sources, Expression expression) { var methodCallExpression = expression as MethodCallExpression; MethodInfo methodInfo = methodCallExpression.Method; diff --git a/OData.Neo.Core/Brokers/Expressions/IExpressionBroker.cs b/OData.Neo.Core/Brokers/Expressions/IExpressionBroker.cs index e187fd4..1dfb5e6 100644 --- a/OData.Neo.Core/Brokers/Expressions/IExpressionBroker.cs +++ b/OData.Neo.Core/Brokers/Expressions/IExpressionBroker.cs @@ -12,6 +12,6 @@ namespace OData.Neo.Core.Brokers.Expressions public interface IExpressionBroker { ValueTask GenerateExpressionAsync(string linqExpression); - IQueryable Execute(IQueryable sources, Expression expression); + IQueryable ApplyExpression(IQueryable sources, Expression expression); } } From 339b3391fd9e57a46e7fba2c898ad9d3af3cd172 Mon Sep 17 00:00:00 2001 From: Paul Ward Date: Mon, 13 Mar 2023 20:33:09 +0000 Subject: [PATCH 02/19] ShouldApplyExpressionToSource -> FAIL --- .../OExpressionServiceTests.Logic.cs | 36 ++++++++++++++++++- .../OExpressions/OExpressionServiceTests.cs | 12 +++---- .../Brokers/SqlQueries/ISqlQueryBroker.cs | 2 ++ .../Brokers/SqlQueries/SqlQueryBroker.cs | 6 ++++ .../OExpressions/IOExpressionService.cs | 5 ++- .../OExpressions/OExpressionService.cs | 6 ++++ 6 files changed, 58 insertions(+), 9 deletions(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs index 497b5ec..5d926ac 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs @@ -77,5 +77,39 @@ await this.oExpressionService.GenerateOExpressionAsync( this.expressionBrokerMock.VerifyNoOtherCalls(); } + + [Fact] + public void ShouldApplyExpressionToSource() + { + // given + var randomSource = new List(); + var randomExpression = Expression.Constant(value: default); + IQueryable inputSource = randomSource.AsQueryable(); + Expression inputExpression = randomExpression; + var randomSourceAfterExpression = new List(); + IQueryable expectedSource = randomSourceAfterExpression.AsQueryable(); + + var inputOexpression = new OExpression + { + Expression = inputExpression + }; + + this.expressionBrokerMock.Setup(broker => + broker.ApplyExpression(inputSource, inputExpression)) + .Returns(expectedSource); + + // when + IQueryable actualSource = this.oExpressionService + .ApplyExpression(inputSource, inputOexpression); + + // then + actualSource.Should().BeEquivalentTo(expectedSource); + + this.expressionBrokerMock.Verify(broker => + broker.ApplyExpression(inputSource, inputExpression), + Times.Once); + + this.expressionBrokerMock.VerifyNoOtherCalls(); + } } -} +} \ No newline at end of file diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs index 74b8a32..4203213 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs @@ -3,13 +3,6 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection.Metadata.Ecma335; -using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Scripting; using Moq; @@ -18,6 +11,11 @@ using OData.Neo.Core.Models.OTokens; using OData.Neo.Core.Models.ProjectedTokens; using OData.Neo.Core.Services.Foundations.OExpressions; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Linq.Expressions; using Tynamix.ObjectFiller; using Xunit; diff --git a/OData.Neo.Core/Brokers/SqlQueries/ISqlQueryBroker.cs b/OData.Neo.Core/Brokers/SqlQueries/ISqlQueryBroker.cs index 498dcbd..02a5d29 100644 --- a/OData.Neo.Core/Brokers/SqlQueries/ISqlQueryBroker.cs +++ b/OData.Neo.Core/Brokers/SqlQueries/ISqlQueryBroker.cs @@ -3,6 +3,7 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using System.Linq; using System.Linq.Expressions; namespace OData.Neo.Core.Brokers.Queries @@ -10,5 +11,6 @@ namespace OData.Neo.Core.Brokers.Queries public interface ISqlQueryBroker { string GetSqlQuery(Expression expression); + IQueryable ApplyExpression(IQueryable source, Expression expression); } } diff --git a/OData.Neo.Core/Brokers/SqlQueries/SqlQueryBroker.cs b/OData.Neo.Core/Brokers/SqlQueries/SqlQueryBroker.cs index 50bcbb0..6f3fcd4 100644 --- a/OData.Neo.Core/Brokers/SqlQueries/SqlQueryBroker.cs +++ b/OData.Neo.Core/Brokers/SqlQueries/SqlQueryBroker.cs @@ -3,6 +3,7 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using System; using System.Linq; using System.Linq.Expressions; using Microsoft.EntityFrameworkCore; @@ -31,6 +32,11 @@ public IQueryable Apply(IQueryable source, Expression expression) parameters: new object[] { source, unaryExpression.Operand }); } + public IQueryable ApplyExpression(IQueryable source, Expression expression) + { + throw new NotImplementedException(); + } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs index 51cee11..33fe786 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs @@ -3,6 +3,8 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using System.Linq.Expressions; +using System.Linq; using System.Threading.Tasks; using OData.Neo.Core.Models.OExpressions; @@ -11,5 +13,6 @@ namespace OData.Neo.Core.Services.Foundations.OExpressions public interface IOExpressionService { ValueTask GenerateOExpressionAsync(OExpression oExpression); + IQueryable ApplyExpression(IQueryable sources, OExpression expression); } -} +} \ No newline at end of file diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index 4b2bac6..77c11cb 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -3,6 +3,7 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using System; using System.Linq; using System.Linq.Expressions; using System.Text; @@ -35,6 +36,11 @@ public ValueTask GenerateOExpressionAsync(OExpression oExpressio return oExpression; }); + public IQueryable ApplyExpression(IQueryable sources, OExpression expression) + { + throw new NotImplementedException(); + } + private string CovertToLinqExp(OToken token) { var stringBuilder = new StringBuilder(); From 1ebc84469be0f4b6b1d53a39cecd6fe27fdae8bf Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Mon, 13 Mar 2023 13:37:26 -0700 Subject: [PATCH 03/19] ShouldApplyExpressionToSource -> PASS --- .../Services/Foundations/OExpressions/OExpressionService.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index 77c11cb..a82c59d 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -36,10 +36,8 @@ public ValueTask GenerateOExpressionAsync(OExpression oExpressio return oExpression; }); - public IQueryable ApplyExpression(IQueryable sources, OExpression expression) - { - throw new NotImplementedException(); - } + public IQueryable ApplyExpression(IQueryable sources, OExpression expression) => + this.expressionBroker.ApplyExpression(sources, expression.Expression); private string CovertToLinqExp(OToken token) { From 8b26258acd2c71b216c59a083c18bcd780be66e3 Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Mon, 13 Mar 2023 13:55:10 -0700 Subject: [PATCH 04/19] CODE RUB: Run Code Clean Up & Clean up Test --- ...dinationServiceTests.Exceptions.Process.cs | 3 +-- .../OQueryCoordinationServiceTests.cs | 2 +- .../OExpressionServiceTests.Logic.cs | 27 +++++++++---------- .../OExpressions/OExpressionServiceTests.cs | 19 ++++++++----- .../OQueries/OQueryServiceTests.cs | 2 +- .../OSqlServiceTests.Exceptions.Retrieve.cs | 1 - .../OTokenizationOrchestrationService.cs | 2 +- .../Brokers/Expressions/ExpressionBroker.cs | 7 +++-- OData.Neo.Core/Models/Expressions/Globals.cs | 1 - .../Exceptions/NullOExpressionException.cs | 2 +- ...kenizationOrchestrationServiceException.cs | 4 +-- .../OQueryCoordinationService.Exceptions.cs | 2 +- .../OQueries/OQueryCoordinationService.cs | 1 - .../OExpressions/IOExpressionService.cs | 1 - .../OExpressionService.Validations.cs | 6 ----- .../OExpressions/OExpressionService.cs | 1 - .../OQueries/OQueryService.Exceptions.cs | 5 +--- .../OQueries/OQueryService.Validations.cs | 2 +- .../Foundations/OQueries/OQueryService.cs | 2 +- .../OSqls/OSqlService.Exceptions.cs | 1 - .../OSqls/OSqlService.Validations.cs | 2 -- .../Services/Foundations/OSqls/OSqlService.cs | 2 -- .../Coordinates/IOQueryCoordinateService.cs | 1 - .../OQueries/OQueryOrchestrationService.cs | 2 +- 24 files changed, 41 insertions(+), 57 deletions(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Exceptions.Process.cs b/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Exceptions.Process.cs index 6675de7..7ce73f1 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Exceptions.Process.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Exceptions.Process.cs @@ -9,7 +9,6 @@ using FluentAssertions; using Moq; using OData.Neo.Core.Models.Coordinations.OQueries.Exceptions; -using OData.Neo.Core.Models.Orchestrations.Coordinates.Exceptions; using Xeptions; using Xunit; @@ -99,7 +98,7 @@ public async Task ShouldThrowServiceExceptionOnProcessIfServiceErrorOccursAsync( // given string someOQueryExpression = GetRandomODataQuery(); var exception = new Exception(); - + var failedOQueryCoordinationServiceException = new FailedOQueryCoordinationServiceException( exception); diff --git a/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.cs index 3b2c79f..c4aa902 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.cs @@ -31,7 +31,7 @@ public OQueryCoordinationServiceTests() { this.oTokenizationOrchestrationServiceMock = new Mock(); - + this.oQueryOrchestrationServiceMock = new Mock(); diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs index 5d926ac..a4a854f 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Logic.cs @@ -22,7 +22,7 @@ public partial class OExpressionServiceTests public async Task ShouldGenerateOExpressionAsync() { // given - (List randomPropertyOTokens, string allRawValues) = + (List randomPropertyOTokens, string allRawValues) = CreateRandomPropertyOTokens(); (List randomNonPropertyOTokens, _) = @@ -41,8 +41,8 @@ public async Task ShouldGenerateOExpressionAsync() RawValue = "$select", Type = OTokenType.Select, ProjectedType = ProjectedTokenType.Keyword, - - Children = + + Children = randomPropertyOTokens.Concat(randomNonPropertyOTokens) .ToList() } @@ -82,25 +82,24 @@ await this.oExpressionService.GenerateOExpressionAsync( public void ShouldApplyExpressionToSource() { // given - var randomSource = new List(); + var randomSource = CreateRandomSource(); var randomExpression = Expression.Constant(value: default); - IQueryable inputSource = randomSource.AsQueryable(); + IQueryable inputSource = CreateRandomSource(); Expression inputExpression = randomExpression; - var randomSourceAfterExpression = new List(); - IQueryable expectedSource = randomSourceAfterExpression.AsQueryable(); - - var inputOexpression = new OExpression - { - Expression = inputExpression - }; + IQueryable randomSourceAfterExpression = CreateRandomSource(); + IQueryable expectedSource = randomSourceAfterExpression; + var inputOExpression = new OExpression(); + inputOExpression.Expression = inputExpression; this.expressionBrokerMock.Setup(broker => broker.ApplyExpression(inputSource, inputExpression)) .Returns(expectedSource); // when - IQueryable actualSource = this.oExpressionService - .ApplyExpression(inputSource, inputOexpression); + IQueryable actualSource = + this.oExpressionService.ApplyExpression( + inputSource, + inputOExpression); // then actualSource.Should().BeEquivalentTo(expectedSource); diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs index 4203213..94e3da1 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs @@ -3,6 +3,11 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Linq.Expressions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Scripting; using Moq; @@ -11,11 +16,6 @@ using OData.Neo.Core.Models.OTokens; using OData.Neo.Core.Models.ProjectedTokens; using OData.Neo.Core.Services.Foundations.OExpressions; -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Linq.Expressions; using Tynamix.ObjectFiller; using Xunit; @@ -106,7 +106,7 @@ private static T GetEnumThatIsNot(T notThisValue) where T : Enum int randomNumber = new Random() .Next( - minValue: 0, + minValue: 0, maxValue: allValues.Length); return allValues[randomNumber]; @@ -121,6 +121,13 @@ private static int GetRandomNumber() => private static string GetRandomString() => new MnemonicString().GetValue(); + private static IQueryable CreateRandomSource() + { + return new Filler() + .Create(count: GetRandomNumber()) + .AsQueryable(); + } + private static Filler CreateOExpressionFiller() { var filler = new Filler(); diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OQueries/OQueryServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OQueries/OQueryServiceTests.cs index b5cb16e..76fea5e 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OQueries/OQueryServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OQueries/OQueryServiceTests.cs @@ -46,7 +46,7 @@ private static (List, string) GenerateRandomSqlQueryProperties() int randomNumber = GetRandomNumber(); string randomSqlVariable = GetRandomString(); List properties = new List(); - + string[] sqlProperties = Enumerable.Range(start: 0, count: randomNumber) .Select(item => { diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OSqls/OSqlServiceTests.Exceptions.Retrieve.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OSqls/OSqlServiceTests.Exceptions.Retrieve.cs index 80a94ae..42b281c 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OSqls/OSqlServiceTests.Exceptions.Retrieve.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OSqls/OSqlServiceTests.Exceptions.Retrieve.cs @@ -7,7 +7,6 @@ using System.Linq.Expressions; using FluentAssertions; using Moq; -using OData.Neo.Core.Models.OQueries.Exceptions; using OData.Neo.Core.Models.OSqls.Exceptions; using Xunit; diff --git a/OData.Neo.Core.Tests.Unit/Services/Orchestrations/OTokenizations/OTokenizationOrchestrationService.cs b/OData.Neo.Core.Tests.Unit/Services/Orchestrations/OTokenizations/OTokenizationOrchestrationService.cs index 6822157..c3f948b 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Orchestrations/OTokenizations/OTokenizationOrchestrationService.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Orchestrations/OTokenizations/OTokenizationOrchestrationService.cs @@ -88,7 +88,7 @@ private Expression> SameOTokensAs( actualOTokens) .AreEqual; } - + private static OToken CreateRandomOToken() => CreateOTokenFiller().Create(); diff --git a/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs b/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs index e9c8341..c1beefc 100644 --- a/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs +++ b/OData.Neo.Core/Brokers/Expressions/ExpressionBroker.cs @@ -8,7 +8,6 @@ using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; -using FluentAssertions; using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting; using OData.Neo.Core.Models.Expressions; @@ -38,10 +37,10 @@ public IQueryable ApplyExpression(IQueryable sources, Expression expressio MethodInfo methodInfo = methodCallExpression.Method; var unary = methodCallExpression.Arguments[1] as UnaryExpression; var lambda = unary.Operand as LambdaExpression; - + return methodInfo.Invoke( - obj: null, - parameters: + obj: null, + parameters: new object[] { sources, lambda }) as IQueryable; } diff --git a/OData.Neo.Core/Models/Expressions/Globals.cs b/OData.Neo.Core/Models/Expressions/Globals.cs index b8c359e..77a1ca8 100644 --- a/OData.Neo.Core/Models/Expressions/Globals.cs +++ b/OData.Neo.Core/Models/Expressions/Globals.cs @@ -3,7 +3,6 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using System.Linq; namespace OData.Neo.Core.Models.Expressions diff --git a/OData.Neo.Core/Models/OExpressions/Exceptions/NullOExpressionException.cs b/OData.Neo.Core/Models/OExpressions/Exceptions/NullOExpressionException.cs index d11edf3..1ac6651 100644 --- a/OData.Neo.Core/Models/OExpressions/Exceptions/NullOExpressionException.cs +++ b/OData.Neo.Core/Models/OExpressions/Exceptions/NullOExpressionException.cs @@ -10,7 +10,7 @@ namespace OData.Neo.Core.Models.OExpressions.Exceptions public class NullOExpressionException : Xeption { public NullOExpressionException() - : base (message: "OExpression is null") + : base(message: "OExpression is null") { } } diff --git a/OData.Neo.Core/Models/Orchestrations/OToknizations/Exceptions/FailedTokenizationOrchestrationServiceException.cs b/OData.Neo.Core/Models/Orchestrations/OToknizations/Exceptions/FailedTokenizationOrchestrationServiceException.cs index 1b73064..c11a10f 100644 --- a/OData.Neo.Core/Models/Orchestrations/OToknizations/Exceptions/FailedTokenizationOrchestrationServiceException.cs +++ b/OData.Neo.Core/Models/Orchestrations/OToknizations/Exceptions/FailedTokenizationOrchestrationServiceException.cs @@ -11,8 +11,8 @@ namespace OData.Neo.Core.Models.Orchestrations.OToknizations.Exceptions public class FailedTokenizationOrchestrationServiceException : Xeption { public FailedTokenizationOrchestrationServiceException(Exception innerException) - : base (message: "Failed tokenization service error occurred, contact support.", + : base(message: "Failed tokenization service error occurred, contact support.", innerException) - {} + { } } } diff --git a/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.Exceptions.cs b/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.Exceptions.cs index 062fd22..5f5a87e 100644 --- a/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.Exceptions.cs +++ b/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.Exceptions.cs @@ -69,7 +69,7 @@ private async ValueTask TryCatch(ReturningOQueryFunction returningOQ } catch (Exception exception) { - var failedOQueryCoordinationServiceException = + var failedOQueryCoordinationServiceException = new FailedOQueryCoordinationServiceException(exception); throw new OQueryCoordinationServiceException(failedOQueryCoordinationServiceException); diff --git a/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs b/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs index e63233d..3f8087a 100644 --- a/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs +++ b/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs @@ -3,7 +3,6 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using System.Linq.Expressions; using System.Threading.Tasks; using OData.Neo.Core.Models.OExpressions; diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs index 33fe786..dc40464 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/IOExpressionService.cs @@ -3,7 +3,6 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System.Linq.Expressions; using System.Linq; using System.Threading.Tasks; using OData.Neo.Core.Models.OExpressions; diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs index 5ab3b76..171c944 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs @@ -3,14 +3,8 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; -using OData.Neo.Core.Brokers.Expressions; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Models.OExpressions.Exceptions; -using OData.Neo.Core.Models.OTokens; namespace OData.Neo.Core.Services.Foundations.OExpressions { diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index a82c59d..9b50ee0 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -3,7 +3,6 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using System.Linq; using System.Linq.Expressions; using System.Text; diff --git a/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Exceptions.cs index 675f05a..87a8558 100644 --- a/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Exceptions.cs +++ b/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Exceptions.cs @@ -4,9 +4,6 @@ //----------------------------------------------------------------------- using System; -using System.Threading.Tasks; -using OData.Neo.Core.Models.Coordinations.OQueries.Exceptions; -using OData.Neo.Core.Models.OExpressions.Exceptions; using OData.Neo.Core.Models.OQueries.Exceptions; namespace OData.Neo.Core.Services.Foundations.OQueries @@ -28,7 +25,7 @@ private string TryCatch( } catch (InvalidOperationException invalidOperationException) { - var failedOQueryDependencyException = + var failedOQueryDependencyException = new FailedOQueryDependencyException(invalidOperationException); throw new OQueryDependencyException(failedOQueryDependencyException); diff --git a/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Validations.cs b/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Validations.cs index 3bcc2ea..2625703 100644 --- a/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Validations.cs +++ b/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.Validations.cs @@ -3,8 +3,8 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using OData.Neo.Core.Models.OQueries.Exceptions; using System.Linq.Expressions; +using OData.Neo.Core.Models.OQueries.Exceptions; namespace OData.Neo.Core.Services.Foundations.OQueries { diff --git a/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.cs b/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.cs index 7f7d2f4..2a13caf 100644 --- a/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.cs +++ b/OData.Neo.Core/Services/Foundations/OQueries/OQueryService.cs @@ -40,7 +40,7 @@ private string GenerateOQuery(Expression expression) return string.Join("", result); } - static Dictionary keywords = + static Dictionary keywords = new Dictionary() { { "SELECT", "$select=" } diff --git a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Exceptions.cs index adfe3c4..8f73885 100644 --- a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Exceptions.cs +++ b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Exceptions.cs @@ -4,7 +4,6 @@ //----------------------------------------------------------------------- using System; -using OData.Neo.Core.Models.OExpressions.Exceptions; using OData.Neo.Core.Models.OSqls.Exceptions; namespace OData.Neo.Core.Services.Foundations.OSqls diff --git a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Validations.cs b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Validations.cs index 9a3b2e0..9da750c 100644 --- a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Validations.cs +++ b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.Validations.cs @@ -3,9 +3,7 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using System.Linq.Expressions; -using OData.Neo.Core.Brokers.Queries; using OData.Neo.Core.Models.OSqls.Exceptions; namespace OData.Neo.Core.Services.Foundations.OSqls diff --git a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs index bfd3d84..3002ca6 100644 --- a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs +++ b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs @@ -3,10 +3,8 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using System.Linq.Expressions; using OData.Neo.Core.Brokers.Queries; -using OData.Neo.Core.Models.OSqls.Exceptions; namespace OData.Neo.Core.Services.Foundations.OSqls { diff --git a/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs b/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs index 5f9fb6f..8d3a4c4 100644 --- a/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs +++ b/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs @@ -5,7 +5,6 @@ using System.Linq.Expressions; using System.Threading.Tasks; -using OData.Neo.Core.Models.OExpressions; namespace OData.Neo.Core.Services.Orchestrations.Coordinates { diff --git a/OData.Neo.Core/Services/Orchestrations/OQueries/OQueryOrchestrationService.cs b/OData.Neo.Core/Services/Orchestrations/OQueries/OQueryOrchestrationService.cs index dc59ca7..9d10aec 100644 --- a/OData.Neo.Core/Services/Orchestrations/OQueries/OQueryOrchestrationService.cs +++ b/OData.Neo.Core/Services/Orchestrations/OQueries/OQueryOrchestrationService.cs @@ -3,11 +3,11 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using System.Threading.Tasks; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Services.Foundations.OExpressions; using OData.Neo.Core.Services.Foundations.OQueries; using OData.Neo.Core.Services.Foundations.OSqls; -using System.Threading.Tasks; namespace OData.Neo.Core.Services.Orchestrations.OQueries { From fbf1fa9e197ec5364c89230001bada3b5d15442a Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Thu, 16 Mar 2023 13:27:32 -0700 Subject: [PATCH 05/19] ShouldApplyExpressionToSource -> PASS --- .../Foundations/OExpressions/OExpressionServiceTests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs index 94e3da1..5fc4514 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs @@ -123,9 +123,14 @@ private static string GetRandomString() => private static IQueryable CreateRandomSource() { - return new Filler() + var filler = new Filler(); + + filler.Setup() + .OnType().Use(GetRandomString()); + + return filler .Create(count: GetRandomNumber()) - .AsQueryable(); + .AsQueryable(); } private static Filler CreateOExpressionFiller() From a0c8fd29ee5586a1a521e69bd895b6cfa46bd2ea Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Thu, 16 Mar 2023 13:37:18 -0700 Subject: [PATCH 06/19] ShouldThrowValidationExceptionOnApplyIfSourceIsNull -> FAIL --- ...xpressionServiceTests.Validations.Apply.cs | 56 +++++++++++++++++++ .../NullSourceOExpressionException.cs | 16 ++++++ 2 files changed, 72 insertions(+) create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs create mode 100644 OData.Neo.Core/Models/OExpressions/Exceptions/NullSourceOExpressionException.cs diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs new file mode 100644 index 0000000..8f59175 --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +//----------------------------------------------------------------------- + +using System; +using System.Linq; +using System.Linq.Expressions; +using FluentAssertions; +using Moq; +using OData.Neo.Core.Models.OExpressions; +using OData.Neo.Core.Models.OExpressions.Exceptions; +using Xunit; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.OExpressions +{ + public partial class OExpressionServiceTests + { + [Fact] + public void ShouldThrowValidationExceptionOnApplyIfSourceIsNull() + { + // given + OExpression someOExpression = CreateRandomOExpression(); + IQueryable nullSource = null; + + var nullSourceOExpressionException = + new NullSourceOExpressionException(); + + var expectedOExpressionValidationException = + new OExpressionValidationException( + nullSourceOExpressionException); + + // when + Action applyExpressionAction = () => + this.oExpressionService.ApplyExpression( + nullSource, + someOExpression); + + OExpressionValidationException actualOExpressionValidationException = + Assert.Throws( + applyExpressionAction); + + // then + actualOExpressionValidationException.Should().BeEquivalentTo( + expectedOExpressionValidationException); + + this.expressionBrokerMock.Verify(broker => + broker.ApplyExpression( + It.IsAny>(), + It.IsAny()), + Times.Never); + + this.expressionBrokerMock.VerifyNoOtherCalls(); + } + } +} diff --git a/OData.Neo.Core/Models/OExpressions/Exceptions/NullSourceOExpressionException.cs b/OData.Neo.Core/Models/OExpressions/Exceptions/NullSourceOExpressionException.cs new file mode 100644 index 0000000..7cd4ebb --- /dev/null +++ b/OData.Neo.Core/Models/OExpressions/Exceptions/NullSourceOExpressionException.cs @@ -0,0 +1,16 @@ +//----------------------------------------------------------------------- +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// See License.txt in the project root for license information. +//----------------------------------------------------------------------- + +using Xeptions; + +namespace OData.Neo.Core.Models.OExpressions.Exceptions +{ + public class NullSourceOExpressionException : Xeption + { + public NullSourceOExpressionException() + : base(message: "Source is null") + { } + } +} From 0a1152d7bd16bb5eedba4e77df35fadd8c300267 Mon Sep 17 00:00:00 2001 From: Paul Ward Date: Thu, 16 Mar 2023 20:49:38 +0000 Subject: [PATCH 07/19] ShouldThrowValidationExceptionOnApplyIfSourceIsNull -> PASS --- .../OExpressions/OExpressionService.Exceptions.cs | 14 ++++++++++++++ .../OExpressions/OExpressionService.Validations.cs | 11 +++++++++++ .../Foundations/OExpressions/OExpressionService.cs | 8 +++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs index b641de9..0fc8302 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs @@ -4,6 +4,7 @@ //----------------------------------------------------------------------- using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Scripting; using OData.Neo.Core.Models.OExpressions; @@ -14,6 +15,7 @@ namespace OData.Neo.Core.Services.Foundations.OExpressions public partial class OExpressionService : IOExpressionService { private delegate ValueTask ReturningOExpressionFunction(); + private delegate IQueryable ReturningQueryableFunction(); private async ValueTask TryCatch( ReturningOExpressionFunction returningOExpressionFunction) @@ -59,5 +61,17 @@ private async ValueTask TryCatch( throw new OExpressionServiceException(failedOExpressionServiceException); } } + + private IQueryable TryCatch(ReturningQueryableFunction returningQueryableFunction) + { + try + { + return returningQueryableFunction(); + } + catch (NullSourceOExpressionException nullSourceOExpressionException) + { + throw new OExpressionValidationException(nullSourceOExpressionException); + } + } } } diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs index 171c944..a8ad542 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs @@ -3,8 +3,11 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- +using Microsoft.CodeAnalysis.CSharp.Syntax; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Models.OExpressions.Exceptions; +using System.Linq; +using System.Linq.Expressions; namespace OData.Neo.Core.Services.Foundations.OExpressions { @@ -27,5 +30,13 @@ private static void ValidateOExpression(OExpression oExpression) throw invalidOExpressionException; } } + + private static void ValidateSource(IQueryable source) + { + if (source is null) + { + throw new NullSourceOExpressionException(); + } + } } } diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index 9b50ee0..bc3dcba 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -7,6 +7,7 @@ using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using OData.Neo.Core.Brokers.Expressions; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Models.OTokens; @@ -36,7 +37,12 @@ public ValueTask GenerateOExpressionAsync(OExpression oExpressio }); public IQueryable ApplyExpression(IQueryable sources, OExpression expression) => - this.expressionBroker.ApplyExpression(sources, expression.Expression); + TryCatch(() => + { + ValidateSource(sources); + + return this.expressionBroker.ApplyExpression(sources, expression.Expression); + }); private string CovertToLinqExp(OToken token) { From 5df9683403e493dd60ec7327e3065c8f3904a565 Mon Sep 17 00:00:00 2001 From: Paul Ward Date: Thu, 16 Mar 2023 20:53:20 +0000 Subject: [PATCH 08/19] ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull -> FAIL --- ...xpressionServiceTests.Validations.Apply.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs index 8f59175..5522fdf 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs @@ -52,5 +52,42 @@ public void ShouldThrowValidationExceptionOnApplyIfSourceIsNull() this.expressionBrokerMock.VerifyNoOtherCalls(); } + + [Fact] + public void ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull() + { + // given + OExpression nullOExpression = null; + IQueryable someSource = CreateRandomSource(); + + var nullOExpressionException = + new NullSourceOExpressionException(); + + var expectedOExpressionValidationException = + new OExpressionValidationException( + nullOExpressionException); + + // when + Action applyExpressionAction = () => + this.oExpressionService.ApplyExpression( + someSource, + nullOExpression); + + OExpressionValidationException actualOExpressionValidationException = + Assert.Throws( + applyExpressionAction); + + // then + actualOExpressionValidationException.Should().BeEquivalentTo( + expectedOExpressionValidationException); + + this.expressionBrokerMock.Verify(broker => + broker.ApplyExpression( + It.IsAny>(), + It.IsAny()), + Times.Never); + + this.expressionBrokerMock.VerifyNoOtherCalls(); + } } } From dd1734a149317ded56bc47170731aba9e566470e Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 16 Mar 2023 14:00:01 -0700 Subject: [PATCH 09/19] ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull -> PASS --- .../OExpressions/OExpressionServiceTests.Validations.Apply.cs | 2 +- .../Foundations/OExpressions/OExpressionService.Exceptions.cs | 4 ++++ .../Services/Foundations/OExpressions/OExpressionService.cs | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs index 5522fdf..4ee3e78 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs @@ -61,7 +61,7 @@ public void ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull() IQueryable someSource = CreateRandomSource(); var nullOExpressionException = - new NullSourceOExpressionException(); + new NullOExpressionException(); var expectedOExpressionValidationException = new OExpressionValidationException( diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs index 0fc8302..4778b45 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs @@ -72,6 +72,10 @@ private IQueryable TryCatch(ReturningQueryableFunction returningQueryableFunctio { throw new OExpressionValidationException(nullSourceOExpressionException); } + catch (NullOExpressionException nullOExpressionException) + { + throw new OExpressionValidationException(nullOExpressionException); + } } } } diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index bc3dcba..8c0a262 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -40,6 +40,7 @@ public IQueryable ApplyExpression(IQueryable sources, OExpression expressi TryCatch(() => { ValidateSource(sources); + ValidateOExpression(expression); return this.expressionBroker.ApplyExpression(sources, expression.Expression); }); From e8fad7570e6703c322e0856f274586559dcfc2fa Mon Sep 17 00:00:00 2001 From: Sam Xu Date: Thu, 16 Mar 2023 14:04:22 -0700 Subject: [PATCH 10/19] ShouldThrowValidationExceptionOnApplyIfExpressionIsNull -> FAIL --- ...xpressionServiceTests.Validations.Apply.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs index 4ee3e78..eed2ad2 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs @@ -6,6 +6,7 @@ using System; using System.Linq; using System.Linq.Expressions; +using System.Threading.Tasks; using FluentAssertions; using Moq; using OData.Neo.Core.Models.OExpressions; @@ -89,5 +90,48 @@ public void ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull() this.expressionBrokerMock.VerifyNoOtherCalls(); } + + [Fact] + public void ShouldThrowValidationExceptionOnApplyIfExpressionIsNull() + { + // given + OExpression randomOExpression = CreateRandomOExpression(); + IQueryable someSource = CreateRandomSource(); + OExpression invalidOExpression = randomOExpression; + invalidOExpression.Expression = null; + + var invalidOExpressionException = + new InvalidOExpressionException(); + + invalidOExpressionException.AddData( + key: nameof(OExpression.Expression), + values: "Expression is required"); + + var expectedOExpressionValidationException = + new OExpressionValidationException( + invalidOExpressionException); + + // when + Action applyExpressionAction = () => + this.oExpressionService.ApplyExpression( + someSource, + invalidOExpression); + + OExpressionValidationException actualOExpressionValidationException = + Assert.Throws( + applyExpressionAction); + + // then + actualOExpressionValidationException.Should().BeEquivalentTo( + expectedOExpressionValidationException); + + this.expressionBrokerMock.Verify(broker => + broker.ApplyExpression( + It.IsAny>(), + It.IsAny()), + Times.Never); + + this.expressionBrokerMock.VerifyNoOtherCalls(); + } } } From 86b2e6674df17a795864d9da222f93f10c12f31e Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Thu, 16 Mar 2023 14:11:48 -0700 Subject: [PATCH 11/19] ShouldThrowValidationExceptionOnApplyIfExpressionIsNull -> PASS --- ...xpressionServiceTests.Validations.Apply.cs | 2 +- .../OExpressionService.Exceptions.cs | 4 ++ .../OExpressionService.Validations.cs | 48 +++++++++++++++++-- .../OExpressions/OExpressionService.cs | 2 +- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs index eed2ad2..625301e 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Validations.Apply.cs @@ -105,7 +105,7 @@ public void ShouldThrowValidationExceptionOnApplyIfExpressionIsNull() invalidOExpressionException.AddData( key: nameof(OExpression.Expression), - values: "Expression is required"); + values: "Value is required"); var expectedOExpressionValidationException = new OExpressionValidationException( diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs index 4778b45..e1cddca 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs @@ -76,6 +76,10 @@ private IQueryable TryCatch(ReturningQueryableFunction returningQueryableFunctio { throw new OExpressionValidationException(nullOExpressionException); } + catch (InvalidOExpressionException invalidOExpressionException) + { + throw new OExpressionValidationException(invalidOExpressionException); + } } } } diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs index a8ad542..51ca033 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Models.OExpressions.Exceptions; +using System.Data; using System.Linq; using System.Linq.Expressions; @@ -15,10 +16,7 @@ public partial class OExpressionService : IOExpressionService { private static void ValidateOExpression(OExpression oExpression) { - if (oExpression is null) - { - throw new NullOExpressionException(); - } + ValidateOExpressionIsNotNull(oExpression); var invalidOExpressionException = new InvalidOExpressionException(); @@ -31,12 +29,52 @@ private static void ValidateOExpression(OExpression oExpression) } } + private void ValidateOExpressionOnApply(OExpression oExpression) + { + ValidateOExpressionIsNotNull(oExpression); + + Validate( + (Rule: IsInvalid(oExpression.Expression), + Parameter: nameof(OExpression.Expression))); + } + + private static void ValidateOExpressionIsNotNull(OExpression oExpression) + { + if (oExpression is null) + { + throw new NullOExpressionException(); + } + } + private static void ValidateSource(IQueryable source) { if (source is null) { throw new NullSourceOExpressionException(); - } + } + } + + private static dynamic IsInvalid(object @object) => new + { + Condition = @object is null, + Message = "Value is required" + }; + + private void Validate(params (dynamic Rule, string Parameter)[] validations) + { + var invalidOExpressionException = new InvalidOExpressionException(); + + foreach ((dynamic rule, string parameter) in validations) + { + if (rule.Condition) + { + invalidOExpressionException.UpsertDataList( + key: parameter, + value: rule.Message); + } + } + + invalidOExpressionException.ThrowIfContainsErrors(); } } } diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index 8c0a262..56bc64a 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -40,7 +40,7 @@ public IQueryable ApplyExpression(IQueryable sources, OExpression expressi TryCatch(() => { ValidateSource(sources); - ValidateOExpression(expression); + ValidateOExpressionOnApply(expression); return this.expressionBroker.ApplyExpression(sources, expression.Expression); }); From defc3d00b3f38b5a9c5205cae51b9915daf3655f Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Thu, 16 Mar 2023 14:14:04 -0700 Subject: [PATCH 12/19] CODE RUB: Make sure existing implementation uses validation engine --- .../OExpressionService.Validations.cs | 16 +++++----------- .../OExpressions/OExpressionService.cs | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs index 51ca033..0a6c2b9 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Validations.cs @@ -14,19 +14,13 @@ namespace OData.Neo.Core.Services.Foundations.OExpressions { public partial class OExpressionService : IOExpressionService { - private static void ValidateOExpression(OExpression oExpression) + private void ValidateOExpressionOnGenerate(OExpression oExpression) { ValidateOExpressionIsNotNull(oExpression); - var invalidOExpressionException = new InvalidOExpressionException(); - - if (oExpression.OToken is null) - { - invalidOExpressionException.UpsertDataList(key: nameof(OExpression.OToken), - value: "Value is required"); - - throw invalidOExpressionException; - } + Validate( + (Rule: IsInvalid(oExpression.OToken), + Parameter: nameof(OExpression.OToken))); } private void ValidateOExpressionOnApply(OExpression oExpression) @@ -34,7 +28,7 @@ private void ValidateOExpressionOnApply(OExpression oExpression) ValidateOExpressionIsNotNull(oExpression); Validate( - (Rule: IsInvalid(oExpression.Expression), + (Rule: IsInvalid(oExpression.Expression), Parameter: nameof(OExpression.Expression))); } diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs index 56bc64a..0f8e9ee 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.cs @@ -25,7 +25,7 @@ public OExpressionService(IExpressionBroker expressionBroker) => public ValueTask GenerateOExpressionAsync(OExpression oExpression) => TryCatch(async () => { - ValidateOExpression(oExpression); + ValidateOExpressionOnGenerate(oExpression); string linqExp = CovertToLinqExp(oExpression.OToken); Expression expression = From eef72689694dae2fd381ea0dc1a9f2437c847195 Mon Sep 17 00:00:00 2001 From: Hassan Habib Date: Thu, 23 Mar 2023 11:56:44 -0700 Subject: [PATCH 13/19] ShouldThrowDependencyExceptionOnApplyIfDependencyErrorOccurs -> FAIL --- .../OExpressionServiceTests.Exceptions.cs | 55 ++++++++++++++++++- .../OExpressions/OExpressionServiceTests.cs | 28 +++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Exceptions.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Exceptions.cs index b91a408..b4ffb67 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Exceptions.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.Exceptions.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; +using System.Linq.Expressions; +using System.Linq; using System.Threading.Tasks; using FluentAssertions; using Moq; @@ -19,7 +21,7 @@ public partial class OExpressionServiceTests { [Theory] [MemberData(nameof(DependencyExceptions))] - public async Task ShouldThrowDependencyExceptionOnGenerateIfDependencyErrorOcurrsAndLogitAsync( + public async Task ShouldThrowDependencyExceptionOnGenerateIfDependencyErrorOccursAsync( Exception dependencyException) { // given @@ -59,7 +61,7 @@ await Assert.ThrowsAsync( } [Fact] - public async Task ShouldThrowServiceExceptionOnGenerateIfServiceErrorOcurrsAndLogitAsync() + public async Task ShouldThrowServiceExceptionOnGenerateIfServiceErrorOccursAsync() { // given OExpression someOExpression = CreateRandomOExpression(); @@ -98,5 +100,54 @@ await Assert.ThrowsAsync( this.expressionBrokerMock.VerifyNoOtherCalls(); } + + + [Theory] + [MemberData(nameof(ApplyDependencyExceptions))] + public void ShouldThrowDependencyExceptionOnApplyIfDependencyErrorOccurs( + Exception dependencyException) + { + // given + IQueryable someSource = CreateRandomSource(); + ConstantExpression someExpression = Expression.Constant(value: default); + var someOExpression = new OExpression(); + someOExpression.Expression = someExpression; + + var failedOExpressionException = + new FailedOExpressionDependencyException( + dependencyException); + + var expectedOExpressionDependencyException = + new OExpressionDependencyException( + failedOExpressionException); + + this.expressionBrokerMock.Setup(broker => + broker.ApplyExpression( + It.IsAny>(), + It.IsAny())) + .Throws(dependencyException); + + // when + Action applyExpressionAction = () => + this.oExpressionService.ApplyExpression( + someSource, + someOExpression); + + OExpressionDependencyException actualOExpressionDependencyException = + Assert.Throws( + applyExpressionAction); + + // then + actualOExpressionDependencyException.Should().BeEquivalentTo( + expectedOExpressionDependencyException); + + this.expressionBrokerMock.Verify(broker => + broker.ApplyExpression( + It.IsAny>(), + It.IsAny()), + Times.Once); + + this.expressionBrokerMock.VerifyNoOtherCalls(); + } } } diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs index 5fc4514..b50c644 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OExpressions/OExpressionServiceTests.cs @@ -8,6 +8,7 @@ using System.Collections.Immutable; using System.Linq; using System.Linq.Expressions; +using System.Reflection; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Scripting; using Moq; @@ -49,6 +50,31 @@ public static TheoryData DependencyExceptions() }; } + public static TheoryData ApplyDependencyExceptions() + { + var someInnerException = new Exception(); + + return new TheoryData + { + new TargetException(), + new TargetParameterCountException(), + new MethodAccessException(), + new TargetInvocationException(someInnerException), + new NotSupportedException() + }; + } + + public static TheoryData ApplyDependencyValidationExceptions() + { + return new TheoryData + { + new InvalidCastException(), + new ArgumentNullException(), + new ArgumentOutOfRangeException(), + new InvalidOperationException() + }; + } + private static (List, string) CreateRandomPropertyOTokens() { var randomOTokens = new List(); @@ -124,7 +150,7 @@ private static string GetRandomString() => private static IQueryable CreateRandomSource() { var filler = new Filler(); - + filler.Setup() .OnType().Use(GetRandomString()); From ebb86baa2c2f2e86566dc98abe8af9c5a19d26fd Mon Sep 17 00:00:00 2001 From: TehWardy Date: Thu, 23 Mar 2023 19:10:21 +0000 Subject: [PATCH 14/19] ShouldThrowDependencyExceptionOnApplyIfDependencyErrorOccurs -> PASS --- .../OExpressionService.Exceptions.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs index e1cddca..ab1f357 100644 --- a/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs +++ b/OData.Neo.Core/Services/Foundations/OExpressions/OExpressionService.Exceptions.cs @@ -5,6 +5,7 @@ using System; using System.Linq; +using System.Reflection; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Scripting; using OData.Neo.Core.Models.OExpressions; @@ -80,6 +81,41 @@ private IQueryable TryCatch(ReturningQueryableFunction returningQueryableFunctio { throw new OExpressionValidationException(invalidOExpressionException); } + catch (TargetException targetException) + { + var failedOExpressionDependencyException = + new FailedOExpressionDependencyException(targetException); + + throw new OExpressionDependencyException(failedOExpressionDependencyException); + } + catch (TargetParameterCountException targetParameterCountException) + { + var failedOExpressionDependencyException = + new FailedOExpressionDependencyException(targetParameterCountException); + + throw new OExpressionDependencyException(failedOExpressionDependencyException); + } + catch (MethodAccessException methodAccessException) + { + var failedOExpressionDependencyException = + new FailedOExpressionDependencyException(methodAccessException); + + throw new OExpressionDependencyException(failedOExpressionDependencyException); + } + catch (TargetInvocationException targetInvocationException) + { + var failedOExpressionDependencyException = + new FailedOExpressionDependencyException(targetInvocationException); + + throw new OExpressionDependencyException(failedOExpressionDependencyException); + } + catch (NotSupportedException notSupportedException) + { + var failedOExpressionDependencyException = + new FailedOExpressionDependencyException(notSupportedException); + + throw new OExpressionDependencyException(failedOExpressionDependencyException); + } } } } From 5ce1b8e617c322aaa6a40a88e1e953aab6f3644f Mon Sep 17 00:00:00 2001 From: Callum Marshall Date: Fri, 16 Feb 2024 11:57:58 +0000 Subject: [PATCH 15/19] FOUNDATION: Introduce Validation Services to retire need for internal mock --- .../OData.Neo.Core.Tests.Unit.csproj | 1 - .../OTokenizationServiceTests.Exceptions.cs | 12 +- .../OTokenizationServiceTests.cs | 10 +- ...okenizationValidationServiceTests.Logic.cs | 107 +++++++++++++++++ .../OTokenizationValidationServiceTests.cs | 49 ++++++++ .../ProjectionServiceTests.Exceptions.cs | 11 +- .../ProjectionServiceTests.Validations.cs | 99 +--------------- .../Projections/ProjectionServiceTests.cs | 9 +- .../ProjectionValidationServiceTests.Logic.cs | 110 +++++++++++++++++ .../ProjectionValidationServiceTests.cs | 112 ++++++++++++++++++ .../TokenizationServiceTests.Exceptions.cs | 11 +- .../TokenizationServiceTests.Validations.cs | 24 +--- .../Tokenizations/TokenizationServiceTests.cs | 16 +-- ...okenizationValidationServiceTests.Logic.cs | 38 ++++++ .../TokenizationValidationServiceTests.cs | 101 ++++++++++++++++ .../Services/Foundations/OSqls/OSqlService.cs | 4 +- .../IOTokenizationValidationService.cs | 9 ++ .../OTokenizations/OTokenizationService.cs | 9 +- ...okenizationValidationService.Exceptions.cs | 36 ++++++ .../OTokenizationValidationService.cs | 46 +++++++ .../IProjectionValidationService.cs | 9 ++ .../Projections/ProjectionService.cs | 9 +- .../ProjectionValidationService.Exceptions.cs | 31 +++++ .../ProjectionValidationService.cs | 48 ++++++++ .../ITokenizationValidationService.cs | 7 ++ .../Tokenizations/TokenizationService.cs | 16 ++- ...okenizationValidationService.Exceptions.cs | 25 ++++ .../TokenizationValidationService.cs | 16 +++ 28 files changed, 810 insertions(+), 165 deletions(-) create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.Logic.cs create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.cs create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.Logic.cs create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.cs create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.Logic.cs create mode 100644 OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.cs create mode 100644 OData.Neo.Core/Services/Foundations/OTokenizations/IOTokenizationValidationService.cs create mode 100644 OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.Exceptions.cs create mode 100644 OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.cs create mode 100644 OData.Neo.Core/Services/Foundations/Projections/IProjectionValidationService.cs create mode 100644 OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.Exceptions.cs create mode 100644 OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.cs create mode 100644 OData.Neo.Core/Services/Foundations/Tokenizations/ITokenizationValidationService.cs create mode 100644 OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.Exceptions.cs create mode 100644 OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.cs diff --git a/OData.Neo.Core.Tests.Unit/OData.Neo.Core.Tests.Unit.csproj b/OData.Neo.Core.Tests.Unit/OData.Neo.Core.Tests.Unit.csproj index 8bf9ca5..a57a8d2 100644 --- a/OData.Neo.Core.Tests.Unit/OData.Neo.Core.Tests.Unit.csproj +++ b/OData.Neo.Core.Tests.Unit/OData.Neo.Core.Tests.Unit.csproj @@ -10,7 +10,6 @@ - diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.Exceptions.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.Exceptions.cs index 45456dd..3275c38 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.Exceptions.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.Exceptions.cs @@ -3,11 +3,11 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using FluentAssertions; -using InternalMock.Extensions; +using Moq; using OData.Neo.Core.Models.OTokens; using OData.Neo.Core.Models.OTokens.Exceptions; +using System; using Xunit; namespace OData.Neo.Core.Tests.Unit.Services.Foundations.OTokenizations @@ -31,9 +31,9 @@ public void ShouldThrowServiceExceptionOnTokenizationIfServiceErrorOccurs() new OTokenServiceException( failedOTokenServiceException); - this.tokenizationService.Mock( - methodName: "ValidateOTokens") - .Throws(serviceException); + tokenizationValidationServiceMock.Setup(tokenizationValidationServiceMock => + tokenizationValidationServiceMock.ValidateOTokens(It.IsAny())) + .Throws(expectedOTokenServiceException); // when Action toknizationAction = () => @@ -47,8 +47,6 @@ public void ShouldThrowServiceExceptionOnTokenizationIfServiceErrorOccurs() // then actualOTokenValidationException.Should() .BeEquivalentTo(expectedOTokenServiceException); - - this.tokenizationService.ClearAllOtherCalls(); } } } diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.cs index 88a6d46..6e70457 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationServiceTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; +using Moq; using OData.Neo.Core.Models.OTokens; using OData.Neo.Core.Services.Foundations.OTokenizations; using Tynamix.ObjectFiller; @@ -15,9 +16,12 @@ namespace OData.Neo.Core.Tests.Unit.Services.Foundations.OTokenizations public partial class OTokenizationServiceTests { private readonly IOTokenizationService tokenizationService; - - public OTokenizationServiceTests() => - this.tokenizationService = new OTokenizationService(); + private readonly Mock tokenizationValidationServiceMock; + public OTokenizationServiceTests() + { + this.tokenizationValidationServiceMock = new Mock(); + this.tokenizationService = new OTokenizationService(tokenizationValidationServiceMock.Object); + } private static OToken[] CreateRandomOTokens(OToken addedOToken) { diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.Logic.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.Logic.cs new file mode 100644 index 0000000..150241f --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.Logic.cs @@ -0,0 +1,107 @@ +using OData.Neo.Core.Models.OTokens.Exceptions; +using OData.Neo.Core.Models.OTokens; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; +using FluentAssertions; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.OTokenizations +{ + public partial class OTokenizationValidationServiceTests + { + [Fact] + public void ShouldThrowValidationExceptionOnTokenizeIfOTokensIsNull() + { + // given + OToken[] invalidOTokens = null; + + var nullOTokensException = + new NullOTokensException(); + + var expectedOTokenValidationException = + new OTokenValidationException(nullOTokensException); + + // when + Action oTokenizeAction = () => + this.tokenizationValidationService.ValidateOTokens(invalidOTokens); + + OTokenValidationException actualOTokenValidationException = + Assert.Throws( + oTokenizeAction); + + // then + actualOTokenValidationException.Should().BeEquivalentTo( + expectedOTokenValidationException); + } + + [Fact] + public void ShouldThrowValidationExceptionIfAnyOTokenIsNull() + { + // given + OToken nullOToken = null; + OToken[] randomOTokens = CreateRandomOTokens(nullOToken); + OToken[] invalidProjectedTokens = randomOTokens; + var nullProjectedTokenException = new NullOTokenException(); + + var expectedProjectedTokenValidationException = + new OTokenValidationException( + nullProjectedTokenException); + + // when + Action tokenizeAction = () => + this.tokenizationValidationService.ValidateOTokens( + invalidProjectedTokens); + + OTokenValidationException actualProjectedTokenValidationException = + Assert.Throws( + tokenizeAction); + + // then + actualProjectedTokenValidationException.Should() + .BeEquivalentTo(expectedProjectedTokenValidationException); + } + + + [Theory] + [InlineData(null)] + [InlineData("")] + public void ShouldThrowValidationExceptionIfAnyOTokenRawValuesIsInvalid( + string invalidRawData) + { + // given + OToken invalidOToken = new OToken + { + RawValue = invalidRawData + }; + + OToken[] randomOTokens = + CreateRandomOTokens(invalidOToken); + + OToken[] invalidOTokens = + randomOTokens; + + var invalidOTokenRawValueException = + new InvalidOTokenRawValueException(); + + var expectedOTokenValidationException = + new OTokenValidationException( + invalidOTokenRawValueException); + + // when + Action tokenizeAction = () => + this.tokenizationValidationService.ValidateOTokens( + invalidOTokens); + + OTokenValidationException actualOTokenValidationException = + Assert.Throws( + tokenizeAction); + + // then + actualOTokenValidationException.Should() + .BeEquivalentTo(expectedOTokenValidationException); + } + } +} diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.cs new file mode 100644 index 0000000..815f10e --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/OTokenizations/OTokenizationValidationServiceTests.cs @@ -0,0 +1,49 @@ +using OData.Neo.Core.Models.OTokens; +using OData.Neo.Core.Services.Foundations.OTokenizations; +using System.Collections.Generic; +using System.Linq; +using Tynamix.ObjectFiller; +using Randomizer = System.Random; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.OTokenizations +{ + public partial class OTokenizationValidationServiceTests + { + private readonly IOTokenizationValidationService tokenizationValidationService; + + public OTokenizationValidationServiceTests() + { + tokenizationValidationService = new OTokenizationValidationService(); + } + + private static OToken[] CreateRandomOTokens(OToken addedOToken) + { + List randomOTokens = + CreateOTokenFiller() + .Create(count: GetRandomNumber()) + .ToList(); + + randomOTokens.Add(addedOToken); + + return ShuffleOTokens(randomOTokens).ToArray(); + } + + private static OToken[] CreateRandomOTokens() => + CreateOTokenFiller().Create(count: GetRandomNumber()).ToArray(); + + private static List ShuffleOTokens(List projectedTokens) + { + var randomizer = new Randomizer(); + + return projectedTokens + .OrderBy(token => randomizer.Next()) + .ToList(); ; + } + + private static int GetRandomNumber() => + new IntRange(min: 2, max: 10).GetValue(); + + private static Filler CreateOTokenFiller() => + new Filler(); + } +} diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Exceptions.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Exceptions.cs index 655ef1a..879d33e 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Exceptions.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Exceptions.cs @@ -3,11 +3,10 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; using FluentAssertions; -using InternalMock.Extensions; using OData.Neo.Core.Models.ProjectedTokens; using OData.Neo.Core.Models.ProjectedTokens.Exceptions; +using System; using Xunit; namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Projections @@ -31,9 +30,9 @@ public void ShouldThrowServiceExceptionOnProjectIfServiceErrorOccurs() new ProjectedTokenServiceException( failedProjectedTokenServiceException); - this.projectionService.Mock( - methodName: "ValidateProjectedTokens") - .Throws(serviceException); + projectionValidationServiceMock.Setup(projectionValidationServiceMock => + projectionValidationServiceMock.ValidateProjectedTokens(someProjectedTokens)) + .Throws(expectedProjectedTokenServiceException); // when Action projectTokensAction = () => @@ -47,8 +46,6 @@ public void ShouldThrowServiceExceptionOnProjectIfServiceErrorOccurs() actualProjectedTokenValidationException.InnerException.Should() .BeOfType(); - - this.projectionService.ClearAllOtherCalls(); } } } diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Validations.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Validations.cs index 59bc27a..767ad53 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Validations.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.Validations.cs @@ -13,103 +13,6 @@ namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Projections { public partial class ProjectionServiceTests { - [Fact] - public void ShouldThrowValidationExceptionOnProjectIfTokensIsNull() - { - // given - ProjectedToken[] nullProjectedTokens = null; - - var nullProjectedTokenException = - new NullProjectedTokenException(); - - var projectedTokenValidationException = - new ProjectedTokenValidationException( - nullProjectedTokenException); - - // when - Action projectTokensAction = () => - this.projectionService.ProjectTokens( - nullProjectedTokens); - - // then - ProjectedTokenValidationException actualProjectedTokenValidationException = - Assert.Throws( - projectTokensAction); - - actualProjectedTokenValidationException.InnerException.Should() - .BeOfType(); - } - - [Fact] - public void ShouldThrowValidationExceptionIfAnyProjectedTokenIsNull() - { - // given - ProjectedToken nullProjectedToken = null; - - ProjectedToken[] randomProjectedTokens = - CreateRandomProjectedTokens(nullProjectedToken); - - ProjectedToken[] invalidProjectedTokens = - randomProjectedTokens; - - var nullProjectedTokenException = - new NullProjectedTokenException(); - - var expectedProjectedTokenValidationException = - new ProjectedTokenValidationException( - nullProjectedTokenException); - - // when - Action projectTokensAction = () => - this.projectionService.ProjectTokens( - invalidProjectedTokens); - - // then - ProjectedTokenValidationException actualProjectedTokenValidationException = - Assert.Throws( - projectTokensAction); - - actualProjectedTokenValidationException.InnerException.Should() - .BeOfType(); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - public void ShouldThrowValidationExceptionIfAnyProjectedTokenRawValuesIsNull( - string invalidRawData) - { - // given - ProjectedToken invalidProjectedToken = new ProjectedToken - { - RawValue = invalidRawData - }; - - ProjectedToken[] randomProjectedTokens = - CreateRandomProjectedTokens(invalidProjectedToken); - - ProjectedToken[] invalidProjectedTokens = - randomProjectedTokens; - - var invalidProjectedTokenRawValueException = - new InvalidProjectedTokenRawValueException(); - - var expectedProjectedTokenValidationException = - new ProjectedTokenValidationException( - invalidProjectedTokenRawValueException); - - // when - Action projectTokensAction = () => - this.projectionService.ProjectTokens( - invalidProjectedTokens); - - // then - ProjectedTokenValidationException actualProjectedTokenValidationException = - Assert.Throws( - projectTokensAction); - - actualProjectedTokenValidationException.InnerException.Should() - .BeOfType(); - } + } } diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.cs index 554cb52..8057b1c 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionServiceTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; +using Moq; using OData.Neo.Core.Models.ProjectedTokens; using OData.Neo.Core.Models.Tokens; using OData.Neo.Core.Services.Foundations.Projections; @@ -16,10 +17,14 @@ namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Projections { public partial class ProjectionServiceTests { + private readonly Mock projectionValidationServiceMock; private readonly IProjectionService projectionService; - public ProjectionServiceTests() => - projectionService = new ProjectionService(); + public ProjectionServiceTests() + { + projectionValidationServiceMock = new Mock(); + projectionService = new ProjectionService(projectionValidationServiceMock.Object); + } public static TheoryData ProjectedTokens() { diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.Logic.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.Logic.cs new file mode 100644 index 0000000..aab31b9 --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.Logic.cs @@ -0,0 +1,110 @@ +using FluentAssertions; +using OData.Neo.Core.Models.ProjectedTokens; +using OData.Neo.Core.Models.ProjectedTokens.Exceptions; +using System; +using Xunit; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Projections +{ + public partial class ProjectionValidationServiceTests + { + [Fact] + public void ShouldThrowValidationExceptionOnProjectIfTokensIsNull() + { + // given + ProjectedToken[] nullProjectedTokens = null; + + var nullProjectedTokenException = + new NullProjectedTokenException(); + + var projectedTokenValidationException = + new ProjectedTokenValidationException( + nullProjectedTokenException); + + // when + Action projectTokensAction = () => + this.projectionValidationService.ValidateProjectedTokens( + nullProjectedTokens); + + // then + ProjectedTokenValidationException actualProjectedTokenValidationException = + Assert.Throws( + projectTokensAction); + + actualProjectedTokenValidationException.InnerException.Should() + .BeOfType(); + } + + [Fact] + public void ShouldThrowValidationExceptionIfAnyProjectedTokenIsNull() + { + // given + ProjectedToken nullProjectedToken = null; + + ProjectedToken[] randomProjectedTokens = + CreateRandomProjectedTokens(nullProjectedToken); + + ProjectedToken[] invalidProjectedTokens = + randomProjectedTokens; + + var nullProjectedTokenException = + new NullProjectedTokenException(); + + var expectedProjectedTokenValidationException = + new ProjectedTokenValidationException( + nullProjectedTokenException); + + // when + Action projectTokensAction = () => + this.projectionValidationService.ValidateProjectedTokens( + invalidProjectedTokens); + + // then + ProjectedTokenValidationException actualProjectedTokenValidationException = + Assert.Throws( + projectTokensAction); + + actualProjectedTokenValidationException.InnerException.Should() + .BeOfType(); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void ShouldThrowValidationExceptionIfAnyProjectedTokenRawValuesIsNull( + string invalidRawData) + { + // given + ProjectedToken invalidProjectedToken = new ProjectedToken + { + RawValue = invalidRawData + }; + + ProjectedToken[] randomProjectedTokens = + CreateRandomProjectedTokens(invalidProjectedToken); + + ProjectedToken[] invalidProjectedTokens = + randomProjectedTokens; + + var invalidProjectedTokenRawValueException = + new InvalidProjectedTokenRawValueException(); + + var expectedProjectedTokenValidationException = + new ProjectedTokenValidationException( + invalidProjectedTokenRawValueException); + + // when + Action projectTokensAction = () => + this.projectionValidationService.ValidateProjectedTokens( + invalidProjectedTokens); + + // then + ProjectedTokenValidationException actualProjectedTokenValidationException = + Assert.Throws( + projectTokensAction); + + actualProjectedTokenValidationException.InnerException.Should() + .BeOfType(); + } + } +} diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.cs new file mode 100644 index 0000000..b4d90a2 --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Projections/ProjectionValidationServiceTests.cs @@ -0,0 +1,112 @@ +using OData.Neo.Core.Models.ProjectedTokens; +using OData.Neo.Core.Models.Tokens; +using OData.Neo.Core.Services.Foundations.Projections; +using System.Collections.Generic; +using System.Linq; +using Tynamix.ObjectFiller; +using Xunit; +using Randomizer = System.Random; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Projections +{ + public partial class ProjectionValidationServiceTests + { + private readonly IProjectionValidationService projectionValidationService; + + public ProjectionValidationServiceTests() + { + projectionValidationService = new ProjectionValidationService(); + } + + public static TheoryData ProjectedTokens() + { + int randomNumber = GetRandomNumber(); + var inputProjectedTokens = new List(); + var expectedProjectedTokens = new List(); + + for (int i = 0; i < randomNumber; i++) + { + (string rawValue, ProjectedTokenType projectedType, TokenType tokenType) = + GetRandomProjectedTokenProperties(); + + inputProjectedTokens.Add(item: new ProjectedToken + { + ProjectedType = ProjectedTokenType.Unidentified, + RawValue = rawValue, + TokenType = tokenType + }); + + expectedProjectedTokens.Add(item: new ProjectedToken + { + ProjectedType = projectedType, + RawValue = rawValue, + TokenType = tokenType + }); + } + + return new TheoryData + { + { + inputProjectedTokens.ToArray(), + expectedProjectedTokens.ToArray() + } + }; + } + + private static ProjectedToken[] CreateRandomProjectedTokens(ProjectedToken addedProjectedToken) + { + List randomProjectedTokens = + CreateProjectedTokenFiller() + .Create(count: GetRandomNumber()) + .ToList(); + + randomProjectedTokens.Add(addedProjectedToken); + + return ShuffleProjectedTokens(randomProjectedTokens).ToArray(); + } + + private static ProjectedToken[] CreateRandomProjectedTokens() => + CreateProjectedTokenFiller().Create(count: GetRandomNumber()).ToArray(); + + private static List ShuffleProjectedTokens(List projectedTokens) + { + var randomizer = new Randomizer(); + + return projectedTokens + .OrderBy(token => randomizer.Next()) + .ToList(); ; + } + + private static (string rawValue, ProjectedTokenType projectedType, TokenType tokenType) + GetRandomProjectedTokenProperties() + { + var listOfProjectedTokenProperties = + new List<(string rawValue, ProjectedTokenType projectedType, TokenType tokenType)>() + { + (GetRandomKeyword(), ProjectedTokenType.Keyword, TokenType.Word), + ("=", ProjectedTokenType.Assignment, TokenType.Separator), + (GetRandomWord(), ProjectedTokenType.Property, TokenType.Word), + (" ", ProjectedTokenType.Space, TokenType.Separator), + ("eq", ProjectedTokenType.Equals, TokenType.Word), + (",", ProjectedTokenType.Comma, TokenType.Separator) + }; + + int randomIndex = + new IntRange(min: 0, max: listOfProjectedTokenProperties.Count).GetValue(); + + return listOfProjectedTokenProperties[randomIndex]; + } + + private static string GetRandomWord() => + new MnemonicString().GetValue(); + + private static string GetRandomKeyword() => + $"${GetRandomWord()}"; + + private static int GetRandomNumber() => + new IntRange(min: 2, max: 10).GetValue(); + + private static Filler CreateProjectedTokenFiller() => + new Filler(); + } +} diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Exceptions.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Exceptions.cs index 7b43a69..3a2857b 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Exceptions.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Exceptions.cs @@ -3,9 +3,8 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; -using InternalMock.Extensions; using OData.Neo.Core.Models.Tokens.Exceptions; +using System; using Xunit; @@ -20,9 +19,9 @@ public void ShouldThrowServiceExceptionOnTokenizeIfExceptionOccurs() string someQuery = GetRandomWordValue(); var exception = new Exception(); - this.tokenizationService.Mock( - methodName: "ValidateOTokenQuery") - .Throws(exception); + tokenizationValidationServiceMock.Setup(tokenizationValidationServiceMock => + tokenizationValidationServiceMock.ValidateOTokenQuery(someQuery)) + .Throws(exception); // when Action tokenizationAction = () => @@ -34,8 +33,6 @@ public void ShouldThrowServiceExceptionOnTokenizeIfExceptionOccurs() Assert.True(otokenServiceException.InnerException is FailedOTokenServiceException); - - this.tokenizationService.ClearAllOtherCalls(); } } } \ No newline at end of file diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Validations.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Validations.cs index 694550f..bf50201 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Validations.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.Validations.cs @@ -13,28 +13,6 @@ namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Tokenizations { public partial class TokenizationServiceTests { - [Fact] - public void ShouldThrowValidationExceptionOnTokenizeIfQueryIsNull() - { - // given - string nullQuery = null; - - var nullOTokenException = - new NullOTokenQueryException(); - - var expectedOtokenValidationException = - new TokenValidationException(nullOTokenException); - - // when - Action toknizeAction = () => - this.tokenizationService.Tokenize(nullQuery); - - TokenValidationException actualOTokenValidationException = - Assert.Throws(toknizeAction); - - // then - actualOTokenValidationException.Should().BeEquivalentTo( - expectedOtokenValidationException); - } + } } \ No newline at end of file diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.cs index 7aaedf4..32ff44b 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationServiceTests.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Moq; using OData.Neo.Core.Models.Tokens; using OData.Neo.Core.Services.Foundations.Tokenizations; using Tynamix.ObjectFiller; @@ -14,14 +15,15 @@ namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Tokenizations { public partial class TokenizationServiceTests { - private static readonly string[] separators; - private readonly ITokenizationService tokenizationService; + static readonly string[] separators = new string[] { "\'", " ", "=", "\\" }; + readonly ITokenizationService tokenizationService; + readonly Mock tokenizationValidationServiceMock; - static TokenizationServiceTests() => - separators = new string[] { "\'", " ", "=", "\\" }; - - public TokenizationServiceTests() => - tokenizationService = new TokenizationService(); + public TokenizationServiceTests() + { + tokenizationValidationServiceMock = new Mock(); + tokenizationService = new TokenizationService(tokenizationValidationServiceMock.Object); + } public static (string Query, Token[] Tokens) GetRandomQuery(int numberOfTokens = 25) { diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.Logic.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.Logic.cs new file mode 100644 index 0000000..ef96ca8 --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.Logic.cs @@ -0,0 +1,38 @@ +using FluentAssertions; +using OData.Neo.Core.Models.Tokens.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Tokenizations +{ + public partial class TokenizationValidationServiceTests + { + [Fact] + public void ShouldThrowValidationExceptionOnTokenizeIfQueryIsNull() + { + // given + string nullQuery = null; + + var nullOTokenException = + new NullOTokenQueryException(); + + var expectedOtokenValidationException = + new TokenValidationException(nullOTokenException); + + // when + Action toknizeAction = () => + this.tokenizationValidationService.ValidateOTokenQuery(nullQuery); + + TokenValidationException actualOTokenValidationException = + Assert.Throws(toknizeAction); + + // then + actualOTokenValidationException.Should().BeEquivalentTo( + expectedOtokenValidationException); + } + } +} diff --git a/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.cs b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.cs new file mode 100644 index 0000000..4fa13af --- /dev/null +++ b/OData.Neo.Core.Tests.Unit/Services/Foundations/Tokenizations/TokenizationValidationServiceTests.cs @@ -0,0 +1,101 @@ +using OData.Neo.Core.Models.Tokens; +using OData.Neo.Core.Services.Foundations.Tokenizations; +using System; +using System.Collections.Generic; +using System.Linq; +using Tynamix.ObjectFiller; + +namespace OData.Neo.Core.Tests.Unit.Services.Foundations.Tokenizations +{ + public partial class TokenizationValidationServiceTests + { + static readonly string[] separators = new string[] { "\'", " ", "=", "\\" }; + + private readonly ITokenizationValidationService tokenizationValidationService; + + public TokenizationValidationServiceTests() + { + tokenizationValidationService = new TokenizationValidationService(); + } + + public static (string Query, Token[] Tokens) GetRandomQuery(int numberOfTokens = 25) + { + int numberOfTokensToReturn = 1; + if (numberOfTokens > 1) + { + IntRange intRange = new IntRange(1, numberOfTokens); + numberOfTokensToReturn = intRange.GetValue(); + } + + List results = new List(); + while (results.Count < numberOfTokensToReturn) + { + TokenType nextTokenType = GetRandomTokenType(); + if (IsNotWordType(nextTokenType) || LastIsNotWordType(results)) + { + Token nextToken = GetNextRandomToken(nextTokenType); + results.Add(nextToken); + } + } + + string query = GetQueryFromTokens(results); + Token[] tokens = results.ToArray(); + return new(query, tokens); + } + + private static bool LastIsNotWordType(in List tokens) + { + if (tokens.Count == 0) + { + return true; + } + + return IsNotWordType(tokens.Last()); + } + + private static bool IsNotWordType(in Token token) + { + return token.Type != TokenType.Word; + } + + private static bool IsNotWordType(in TokenType tokenType) + { + return tokenType != TokenType.Word; + } + + private static string GetQueryFromTokens(IEnumerable tokens) + { + IEnumerable tokenValues = tokens.Select(token => token.Value); + string result = string.Join(separator: null, values: tokenValues); + return result; + } + + private static TokenType GetRandomTokenType() + { + TokenType[] knownTokenTypes = Enum.GetValues(); + IntRange intRange = new IntRange(0, knownTokenTypes.Length); + int resultIndex = intRange.GetValue(); + return knownTokenTypes[resultIndex]; + } + + private static Token GetNextRandomToken(TokenType tokenType) + { + string value = tokenType switch + { + TokenType.Word => GetRandomWordValue(), + _ => GetRandomSeperatorValue(), + }; + return new Token(tokenType, value); + } + + private static string GetRandomWordValue() + => new MnemonicString().GetValue(); + + private static string GetRandomSeperatorValue() + { + IntRange intRange = new IntRange(min: 0, max: separators.Length); + int selector = intRange.GetValue(); + return separators[selector]; + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs index bfd3d84..5a78745 100644 --- a/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs +++ b/OData.Neo.Core/Services/Foundations/OSqls/OSqlService.cs @@ -3,10 +3,8 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; -using System.Linq.Expressions; using OData.Neo.Core.Brokers.Queries; -using OData.Neo.Core.Models.OSqls.Exceptions; +using System.Linq.Expressions; namespace OData.Neo.Core.Services.Foundations.OSqls { diff --git a/OData.Neo.Core/Services/Foundations/OTokenizations/IOTokenizationValidationService.cs b/OData.Neo.Core/Services/Foundations/OTokenizations/IOTokenizationValidationService.cs new file mode 100644 index 0000000..71f9057 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/OTokenizations/IOTokenizationValidationService.cs @@ -0,0 +1,9 @@ +using OData.Neo.Core.Models.OTokens; + +namespace OData.Neo.Core.Services.Foundations.OTokenizations +{ + public interface IOTokenizationValidationService + { + void ValidateOTokens(OToken[] oTokens); + } +} \ No newline at end of file diff --git a/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationService.cs b/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationService.cs index db28dc9..6a108d4 100644 --- a/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationService.cs +++ b/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationService.cs @@ -12,10 +12,17 @@ namespace OData.Neo.Core.Services.Foundations.OTokenizations { public partial class OTokenizationService : IOTokenizationService { + private readonly IOTokenizationValidationService oTokenizationValidationService; + + public OTokenizationService(IOTokenizationValidationService oTokenizationValidationService) + { + this.oTokenizationValidationService = oTokenizationValidationService; + } + public OToken OTokenize(OToken[] oTokens) => TryCatch(() => { - ValidateOTokens(oTokens); + oTokenizationValidationService.ValidateOTokens(oTokens); OToken root = new() { diff --git a/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.Exceptions.cs new file mode 100644 index 0000000..eb053ee --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.Exceptions.cs @@ -0,0 +1,36 @@ +using OData.Neo.Core.Models.OTokens.Exceptions; +using System; + +namespace OData.Neo.Core.Services.Foundations.OTokenizations +{ + public partial class OTokenizationValidationService + { + private static void TryCatch(Action action) + { + try + { + action(); + } + catch (NullOTokensException nullOTokensException) + { + throw new OTokenValidationException(nullOTokensException); + } + catch (NullOTokenException nullOTokenException) + { + throw new OTokenValidationException(nullOTokenException); + } + catch (InvalidOTokenRawValueException invalidOTokenRawValueException) + { + throw new OTokenValidationException(invalidOTokenRawValueException); + } + catch (Exception exception) + { + var failedOTokenServiceException = + new FailedOTokenServiceException(exception); + + throw new OTokenServiceException( + failedOTokenServiceException); + } + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.cs b/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.cs new file mode 100644 index 0000000..bdc6886 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/OTokenizations/OTokenizationValidationService.cs @@ -0,0 +1,46 @@ +using OData.Neo.Core.Models.OTokens; +using OData.Neo.Core.Models.OTokens.Exceptions; +using System.Linq; + +namespace OData.Neo.Core.Services.Foundations.OTokenizations +{ + public partial class OTokenizationValidationService : IOTokenizationValidationService + { + public void ValidateOTokens(OToken[] oTokens) + => TryCatch(() => + { + ValidateOTokensIsNotNull(oTokens); + ValidateAllOTokensAreNotNull(oTokens); + ValidateOTokensRawValues(oTokens); + }); + + private static void ValidateOTokensIsNotNull( + OToken[] oTokens) + { + if (oTokens is null) + { + throw new NullOTokensException(); + } + } + + private static void ValidateAllOTokensAreNotNull( + OToken[] oTokens) + { + if (oTokens.Any(oToken => oToken is null)) + { + throw new NullOTokenException(); + } + } + + private static void ValidateOTokensRawValues(OToken[] otokens) + { + if (otokens.Any(IsNullOrEmpty)) + { + throw new InvalidOTokenRawValueException(); + } + + static bool IsNullOrEmpty(OToken oToken) => + oToken.RawValue is null or ""; + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/Projections/IProjectionValidationService.cs b/OData.Neo.Core/Services/Foundations/Projections/IProjectionValidationService.cs new file mode 100644 index 0000000..601a893 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/Projections/IProjectionValidationService.cs @@ -0,0 +1,9 @@ +using OData.Neo.Core.Models.ProjectedTokens; + +namespace OData.Neo.Core.Services.Foundations.Projections +{ + public interface IProjectionValidationService + { + void ValidateProjectedTokens(ProjectedToken[] projectedTokens); + } +} \ No newline at end of file diff --git a/OData.Neo.Core/Services/Foundations/Projections/ProjectionService.cs b/OData.Neo.Core/Services/Foundations/Projections/ProjectionService.cs index dcc06f0..7bfdd45 100644 --- a/OData.Neo.Core/Services/Foundations/Projections/ProjectionService.cs +++ b/OData.Neo.Core/Services/Foundations/Projections/ProjectionService.cs @@ -9,10 +9,17 @@ namespace OData.Neo.Core.Services.Foundations.Projections { public partial class ProjectionService : IProjectionService { + private readonly IProjectionValidationService projectionValidationService; + + public ProjectionService(IProjectionValidationService projectionValidationService) + { + this.projectionValidationService = projectionValidationService; + } + public ProjectedToken[] ProjectTokens(ProjectedToken[] projectedTokens) => TryCatch(() => { - ValidateProjectedTokens(projectedTokens); + projectionValidationService.ValidateProjectedTokens(projectedTokens); foreach (var projectedToken in projectedTokens) { diff --git a/OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.Exceptions.cs new file mode 100644 index 0000000..f49a4e0 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.Exceptions.cs @@ -0,0 +1,31 @@ +using OData.Neo.Core.Models.ProjectedTokens.Exceptions; +using System; + +namespace OData.Neo.Core.Services.Foundations.Projections +{ + public partial class ProjectionValidationService + { + private static void TryCatch(Action action) + { + try + { + action(); + } + catch (NullProjectedTokenException nullProjectedTokenException) + { + throw new ProjectedTokenValidationException(nullProjectedTokenException); + } + catch (InvalidProjectedTokenRawValueException invalidProjectedTokenRawValueException) + { + throw new ProjectedTokenValidationException(invalidProjectedTokenRawValueException); + } + catch (Exception exception) + { + var failedProjectedTokenServiceException = + new FailedProjectedTokenServiceException(exception); + + throw new ProjectedTokenServiceException(failedProjectedTokenServiceException); + } + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.cs b/OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.cs new file mode 100644 index 0000000..be66275 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/Projections/ProjectionValidationService.cs @@ -0,0 +1,48 @@ +using OData.Neo.Core.Models.ProjectedTokens; +using OData.Neo.Core.Models.ProjectedTokens.Exceptions; +using System; +using System.Linq; + +namespace OData.Neo.Core.Services.Foundations.Projections +{ + public partial class ProjectionValidationService : IProjectionValidationService + { + public void ValidateProjectedTokens(ProjectedToken[] projectedTokens) + => TryCatch(() => + { + ValidateProjectedTokensIsNotNull(projectedTokens); + ValidateProjectedTokensContainsNotNullTokens(projectedTokens); + ValidateProjectedTokenRawValuesIsNullNull(projectedTokens); + }); + + private static void ValidateProjectedTokensIsNotNull( + ProjectedToken[] projectedTokens) + { + if (projectedTokens is null) + { + throw new NullProjectedTokenException(); + } + } + + private static void ValidateProjectedTokensContainsNotNullTokens( + ProjectedToken[] projectedTokens) + { + if (projectedTokens.Contains(null)) + { + throw new NullProjectedTokenException(); + } + } + + private static void ValidateProjectedTokenRawValuesIsNullNull( + ProjectedToken[] projectedTokens) + { + Func hasRawValueNullOrEmpty = + token => token.RawValue is null or ""; + + if (projectedTokens.Any(hasRawValueNullOrEmpty)) + { + throw new InvalidProjectedTokenRawValueException(); + } + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/Tokenizations/ITokenizationValidationService.cs b/OData.Neo.Core/Services/Foundations/Tokenizations/ITokenizationValidationService.cs new file mode 100644 index 0000000..2419091 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/Tokenizations/ITokenizationValidationService.cs @@ -0,0 +1,7 @@ +namespace OData.Neo.Core.Services.Foundations.Tokenizations +{ + public interface ITokenizationValidationService + { + void ValidateOTokenQuery(string query); + } +} \ No newline at end of file diff --git a/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs index d2e639a..5c133d9 100644 --- a/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs +++ b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs @@ -12,15 +12,21 @@ namespace OData.Neo.Core.Services.Foundations.Tokenizations { public partial class TokenizationService : ITokenizationService { + readonly ITokenizationValidationService tokenizationValidationService; readonly char[] SeparatorChars = new char[] { '\'', ' ', '=', '\\' }; - public Token[] Tokenize(string rawQuery) => - TryCatch(() => + public TokenizationService(ITokenizationValidationService tokenizationValidationService) { - ValidateOTokenQuery(rawQuery); + this.tokenizationValidationService = tokenizationValidationService; + } + + public Token[] Tokenize(string rawQuery) => + TryCatch(() => + { + tokenizationValidationService.ValidateOTokenQuery(rawQuery); - return OTokenize(rawQuery, SeparatorChars).ToArray(); - }); + return OTokenize(rawQuery, SeparatorChars).ToArray(); + }); private static IEnumerable OTokenize(string rawQuery, char[] separatorChars) { diff --git a/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.Exceptions.cs b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.Exceptions.cs new file mode 100644 index 0000000..636bead --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.Exceptions.cs @@ -0,0 +1,25 @@ +using OData.Neo.Core.Models.Tokens.Exceptions; +using System; + +namespace OData.Neo.Core.Services.Foundations.Tokenizations +{ + public partial class TokenizationValidationService + { + private void TryCatch(Action action) + { + try + { + action(); + } + catch (NullOTokenQueryException nullOTokenQueryException) + { + throw new TokenValidationException(nullOTokenQueryException); + } + catch (Exception ex) + { + var failedOTokenServiceException = new FailedOTokenServiceException(ex); + throw new TokenServiceException(failedOTokenServiceException); + } + } + } +} diff --git a/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.cs b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.cs new file mode 100644 index 0000000..05b2292 --- /dev/null +++ b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationValidationService.cs @@ -0,0 +1,16 @@ +using OData.Neo.Core.Models.Tokens.Exceptions; + +namespace OData.Neo.Core.Services.Foundations.Tokenizations +{ + public partial class TokenizationValidationService : ITokenizationValidationService + { + public void ValidateOTokenQuery(string query) + => TryCatch(() => + { + if (query is null) + { + throw new NullOTokenQueryException(); + } + }); + } +} From e4a7e1197cbc2ce878cbc541f93c527bb89e979a Mon Sep 17 00:00:00 2001 From: Callum Marshall Date: Fri, 16 Feb 2024 12:25:16 +0000 Subject: [PATCH 16/19] CODE RUB: Avoid passing in private static property --- .../Foundations/Tokenizations/TokenizationService.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs index 5c133d9..7e638d4 100644 --- a/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs +++ b/OData.Neo.Core/Services/Foundations/Tokenizations/TokenizationService.cs @@ -13,7 +13,7 @@ namespace OData.Neo.Core.Services.Foundations.Tokenizations public partial class TokenizationService : ITokenizationService { readonly ITokenizationValidationService tokenizationValidationService; - readonly char[] SeparatorChars = new char[] { '\'', ' ', '=', '\\' }; + readonly char[] seperatorChars = new char[] { '\'', ' ', '=', '\\' }; public TokenizationService(ITokenizationValidationService tokenizationValidationService) { @@ -25,20 +25,20 @@ public Token[] Tokenize(string rawQuery) => { tokenizationValidationService.ValidateOTokenQuery(rawQuery); - return OTokenize(rawQuery, SeparatorChars).ToArray(); + return OTokenize(rawQuery).ToArray(); }); - private static IEnumerable OTokenize(string rawQuery, char[] separatorChars) + private IEnumerable OTokenize(string rawQuery) { string remainingRawQuery = rawQuery; - Func NotSeparatorChar = c => !separatorChars.Contains(c); + Func NotSeparatorChar = c => !seperatorChars.Contains(c); while (remainingRawQuery.Length > 0) { string returnValue = remainingRawQuery; string nextRemainingValue = string.Empty; - var index = remainingRawQuery.IndexOfAny(separatorChars); + var index = remainingRawQuery.IndexOfAny(seperatorChars); if (index is not -1) { int rangeIndex = GetRangeIndex(index); From 3f4bc8092049df0095dc976f03ef24b99bd9d942 Mon Sep 17 00:00:00 2001 From: Callum Marshall Date: Fri, 16 Feb 2024 12:25:36 +0000 Subject: [PATCH 17/19] CODE RUB: Clean up using statements in OQueryCoordinationService --- .../Coordinations/OQueries/OQueryCoordinationService.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs b/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs index e63233d..b4d1f9c 100644 --- a/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs +++ b/OData.Neo.Core/Services/Coordinations/OQueries/OQueryCoordinationService.cs @@ -3,13 +3,12 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Models.OTokens; using OData.Neo.Core.Services.Orchestrations.OQueries; using OData.Neo.Core.Services.Orchestrations.OTokenizations; +using System.Linq.Expressions; +using System.Threading.Tasks; namespace OData.Neo.Core.Services.Coordinations.OQueries { From 77db52e399f5f9c62a0829245b5bed5b6e1d6647 Mon Sep 17 00:00:00 2001 From: Callum Marshall Date: Fri, 16 Feb 2024 12:25:52 +0000 Subject: [PATCH 18/19] CODE RUB: Retire OQueryCoordinateService as OQueryCoordinationService is the correct one --- .../Coordinates/IOQueryCoordinateService.cs | 16 ------- .../OQueryCoordinateService.Exceptions.cs | 34 -------------- .../OQueryCoordinateService.Validations.cs | 11 ----- .../Coordinates/OQueryCoordinateService.cs | 44 ------------------- 4 files changed, 105 deletions(-) delete mode 100644 OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs delete mode 100644 OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Exceptions.cs delete mode 100644 OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Validations.cs delete mode 100644 OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.cs diff --git a/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs b/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs deleted file mode 100644 index 5f9fb6f..0000000 --- a/OData.Neo.Core/Services/Orchestrations/Coordinates/IOQueryCoordinateService.cs +++ /dev/null @@ -1,16 +0,0 @@ -//----------------------------------------------------------------------- -// Copyright (c) .NET Foundation and Contributors. All rights reserved. -// See License.txt in the project root for license information. -//----------------------------------------------------------------------- - -using System.Linq.Expressions; -using System.Threading.Tasks; -using OData.Neo.Core.Models.OExpressions; - -namespace OData.Neo.Core.Services.Orchestrations.Coordinates -{ - public interface IOQueryCoordinateService - { - ValueTask ProcessOQueryAsync(string odataQuery); - } -} diff --git a/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Exceptions.cs b/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Exceptions.cs deleted file mode 100644 index 3fcfa49..0000000 --- a/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Exceptions.cs +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------- -// Copyright (c) .NET Foundation and Contributors. All rights reserved. -// See License.txt in the project root for license information. -//----------------------------------------------------------------------- - -using System; -using System.Linq.Expressions; -using System.Threading.Tasks; -using OData.Neo.Core.Models.Orchestrations.Coordinates.Exceptions; - -namespace OData.Neo.Core.Services.Orchestrations.Coordinates -{ - public partial class OQueryCoordinateService : IOQueryCoordinateService - { - private delegate ValueTask ReturningOExpressionFunction(); - - private async ValueTask TryCatch( - ReturningOExpressionFunction returningOExpressionFunction) - { - try - { - return await returningOExpressionFunction(); - } - catch (Exception exception) - { - var failedOQueryCoordinateServiceException = - new FailedOQueryCoordinateServiceException(exception); - - throw new OQueryCoordinateServiceException( - failedOQueryCoordinateServiceException); - } - } - } -} diff --git a/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Validations.cs b/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Validations.cs deleted file mode 100644 index f4f51ac..0000000 --- a/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.Validations.cs +++ /dev/null @@ -1,11 +0,0 @@ -//----------------------------------------------------------------------- -// Copyright (c) .NET Foundation and Contributors. All rights reserved. -// See License.txt in the project root for license information. -//----------------------------------------------------------------------- - -namespace OData.Neo.Core.Services.Orchestrations.Coordinates -{ - public partial class OQueryCoordinateService : IOQueryCoordinateService - { - } -} diff --git a/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.cs b/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.cs deleted file mode 100644 index a8c4ebc..0000000 --- a/OData.Neo.Core/Services/Orchestrations/Coordinates/OQueryCoordinateService.cs +++ /dev/null @@ -1,44 +0,0 @@ -//----------------------------------------------------------------------- -// Copyright (c) .NET Foundation and Contributors. All rights reserved. -// See License.txt in the project root for license information. -//----------------------------------------------------------------------- - -using System.Linq.Expressions; -using System.Threading.Tasks; -using OData.Neo.Core.Models.OExpressions; -using OData.Neo.Core.Models.OTokens; -using OData.Neo.Core.Services.Orchestrations.OQueries; -using OData.Neo.Core.Services.Orchestrations.OTokenizations; - -namespace OData.Neo.Core.Services.Orchestrations.Coordinates -{ - public partial class OQueryCoordinateService : IOQueryCoordinateService - { - private readonly IOTokenizationOrchestrationService oTokenizationOrchestrationService; - private readonly IOQueryOrchestrationService oQueryOrchestrationService; - - public OQueryCoordinateService( - IOTokenizationOrchestrationService oTokenizationOrchestrationService, - IOQueryOrchestrationService oQueryOrchestrationService) - { - this.oTokenizationOrchestrationService = oTokenizationOrchestrationService; - this.oQueryOrchestrationService = oQueryOrchestrationService; - } - - public ValueTask ProcessOQueryAsync(string odataQuery) => - TryCatch(async () => - { - OToken oToken = this.oTokenizationOrchestrationService.OTokenizeQuery(odataQuery); - - OExpression oExpression = new OExpression - { - OToken = oToken, - RawQuery = odataQuery - }; - - OExpression processedOExpression = await this.oQueryOrchestrationService.ProcessOQueryAsync(oExpression); - - return processedOExpression.Expression; - }); - } -} From 2e0165fba754f7d413247d12be434964e4f3c996 Mon Sep 17 00:00:00 2001 From: Callum Marshall Date: Fri, 16 Feb 2024 12:28:20 +0000 Subject: [PATCH 19/19] CODE RUB: Sort usings --- .../OQueries/OQueryCoordinationServiceTests.Logic.Process.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Logic.Process.cs b/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Logic.Process.cs index bccb3de..1208d4b 100644 --- a/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Logic.Process.cs +++ b/OData.Neo.Core.Tests.Unit/Services/Coordinations/OQueries/OQueryCoordinationServiceTests.Logic.Process.cs @@ -3,12 +3,12 @@ // See License.txt in the project root for license information. //----------------------------------------------------------------------- -using System.Linq.Expressions; -using System.Threading.Tasks; using FluentAssertions; using Moq; using OData.Neo.Core.Models.OExpressions; using OData.Neo.Core.Models.OTokens; +using System.Linq.Expressions; +using System.Threading.Tasks; using Xunit; namespace OData.Neo.Core.Tests.Unit.Services.Coordinations.OQueries