Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FOUNDATIONS: Apply Expression to Source #47

Merged
merged 21 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
affb13a
CODE RUB: Change Method name Execute to ApplyExpression
Mar 13, 2023
339b339
ShouldApplyExpressionToSource -> FAIL
Mar 13, 2023
1ebc844
ShouldApplyExpressionToSource -> PASS
xuzhg Mar 13, 2023
8b26258
CODE RUB: Run Code Clean Up & Clean up Test
hassanhabib Mar 13, 2023
fbf1fa9
ShouldApplyExpressionToSource -> PASS
hassanhabib Mar 16, 2023
a0c8fd2
ShouldThrowValidationExceptionOnApplyIfSourceIsNull -> FAIL
hassanhabib Mar 16, 2023
0a1152d
ShouldThrowValidationExceptionOnApplyIfSourceIsNull -> PASS
Mar 16, 2023
5df9683
ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull -> FAIL
Mar 16, 2023
dd1734a
ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull -> PASS
xuzhg Mar 16, 2023
e8fad75
ShouldThrowValidationExceptionOnApplyIfExpressionIsNull -> FAIL
xuzhg Mar 16, 2023
86b2e66
ShouldThrowValidationExceptionOnApplyIfExpressionIsNull -> PASS
hassanhabib Mar 16, 2023
defc3d0
CODE RUB: Make sure existing implementation uses validation engine
hassanhabib Mar 16, 2023
eef7268
ShouldThrowDependencyExceptionOnApplyIfDependencyErrorOccurs -> FAIL
hassanhabib Mar 23, 2023
ebb86ba
ShouldThrowDependencyExceptionOnApplyIfDependencyErrorOccurs -> PASS
TehWardy Mar 23, 2023
5ce1b8e
FOUNDATION: Introduce Validation Services to retire need for internal…
callummarshall9 Feb 16, 2024
e4a7e11
CODE RUB: Avoid passing in private static property
callummarshall9 Feb 16, 2024
3f4bc80
CODE RUB: Clean up using statements in OQueryCoordinationService
callummarshall9 Feb 16, 2024
77db52e
CODE RUB: Retire OQueryCoordinateService as OQueryCoordinationService…
callummarshall9 Feb 16, 2024
2e0165f
CODE RUB: Sort usings
callummarshall9 Feb 16, 2024
e12d54e
Resolve merging pull request #47 into main
callummarshall9 Feb 16, 2024
0847439
Merge pull request #60 from callummarshall9/main
TehWardy Feb 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion OData.Neo.Core.Tests.Unit/OData.Neo.Core.Tests.Unit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
<ItemGroup>
<PackageReference Include="CompareNETObjects" Version="4.77.0" />
<PackageReference Include="FluentAssertions" Version="6.6.0" />
<PackageReference Include="InternalMock" Version="0.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="Tynamix.ObjectFiller" Version="1.5.7" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -99,7 +98,7 @@ public async Task ShouldThrowServiceExceptionOnProcessIfServiceErrorOccursAsync(
// given
string someOQueryExpression = GetRandomODataQuery();
var exception = new Exception();

var failedOQueryCoordinationServiceException =
new FailedOQueryCoordinationServiceException(
exception);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public OQueryCoordinationServiceTests()
{
this.oTokenizationOrchestrationServiceMock =
new Mock<IOTokenizationOrchestrationService>();

this.oQueryOrchestrationServiceMock =
new Mock<IOQueryOrchestrationService>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -19,7 +21,7 @@ public partial class OExpressionServiceTests
{
[Theory]
[MemberData(nameof(DependencyExceptions))]
public async Task ShouldThrowDependencyExceptionOnGenerateIfDependencyErrorOcurrsAndLogitAsync(
public async Task ShouldThrowDependencyExceptionOnGenerateIfDependencyErrorOccursAsync(
Exception dependencyException)
{
// given
Expand Down Expand Up @@ -59,7 +61,7 @@ await Assert.ThrowsAsync<OExpressionDependencyException>(
}

[Fact]
public async Task ShouldThrowServiceExceptionOnGenerateIfServiceErrorOcurrsAndLogitAsync()
public async Task ShouldThrowServiceExceptionOnGenerateIfServiceErrorOccursAsync()
{
// given
OExpression someOExpression = CreateRandomOExpression();
Expand Down Expand Up @@ -98,5 +100,54 @@ await Assert.ThrowsAsync<OExpressionServiceException>(

this.expressionBrokerMock.VerifyNoOtherCalls();
}


[Theory]
[MemberData(nameof(ApplyDependencyExceptions))]
public void ShouldThrowDependencyExceptionOnApplyIfDependencyErrorOccurs(
Exception dependencyException)
{
// given
IQueryable<object> 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<IQueryable<object>>(),
It.IsAny<Expression>()))
.Throws(dependencyException);

// when
Action applyExpressionAction = () =>
this.oExpressionService.ApplyExpression(
someSource,
someOExpression);

OExpressionDependencyException actualOExpressionDependencyException =
Assert.Throws<OExpressionDependencyException>(
applyExpressionAction);

// then
actualOExpressionDependencyException.Should().BeEquivalentTo(
expectedOExpressionDependencyException);

this.expressionBrokerMock.Verify(broker =>
broker.ApplyExpression(
It.IsAny<IQueryable<object>>(),
It.IsAny<Expression>()),
Times.Once);

this.expressionBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public partial class OExpressionServiceTests
public async Task ShouldGenerateOExpressionAsync()
{
// given
(List<OToken> randomPropertyOTokens, string allRawValues) =
(List<OToken> randomPropertyOTokens, string allRawValues) =
CreateRandomPropertyOTokens();

(List<OToken> randomNonPropertyOTokens, _) =
Expand All @@ -41,8 +41,8 @@ public async Task ShouldGenerateOExpressionAsync()
RawValue = "$select",
Type = OTokenType.Select,
ProjectedType = ProjectedTokenType.Keyword,
Children =

Children =
randomPropertyOTokens.Concat(randomNonPropertyOTokens)
.ToList()
}
Expand Down Expand Up @@ -77,5 +77,38 @@ await this.oExpressionService.GenerateOExpressionAsync<object>(

this.expressionBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldApplyExpressionToSource()
{
// given
var randomSource = CreateRandomSource();
var randomExpression = Expression.Constant(value: default);
IQueryable<object> inputSource = CreateRandomSource();
Expression inputExpression = randomExpression;
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);

// then
actualSource.Should().BeEquivalentTo(expectedSource);

this.expressionBrokerMock.Verify(broker =>
broker.ApplyExpression(inputSource, inputExpression),
Times.Once);

this.expressionBrokerMock.VerifyNoOtherCalls();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//-----------------------------------------------------------------------
// 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 System.Threading.Tasks;
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<object> nullSource = null;

var nullSourceOExpressionException =
new NullSourceOExpressionException();

var expectedOExpressionValidationException =
new OExpressionValidationException(
nullSourceOExpressionException);

// when
Action applyExpressionAction = () =>
this.oExpressionService.ApplyExpression(
nullSource,
someOExpression);

OExpressionValidationException actualOExpressionValidationException =
Assert.Throws<OExpressionValidationException>(
applyExpressionAction);

// then
actualOExpressionValidationException.Should().BeEquivalentTo(
expectedOExpressionValidationException);

this.expressionBrokerMock.Verify(broker =>
broker.ApplyExpression<object>(
It.IsAny<IQueryable<object>>(),
It.IsAny<Expression>()),
Times.Never);

this.expressionBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowValidationExceptionOnApplyIfOexpressionIsNull()
{
// given
OExpression nullOExpression = null;
IQueryable<object> someSource = CreateRandomSource();

var nullOExpressionException =
new NullOExpressionException();

var expectedOExpressionValidationException =
new OExpressionValidationException(
nullOExpressionException);

// when
Action applyExpressionAction = () =>
this.oExpressionService.ApplyExpression(
someSource,
nullOExpression);

OExpressionValidationException actualOExpressionValidationException =
Assert.Throws<OExpressionValidationException>(
applyExpressionAction);

// then
actualOExpressionValidationException.Should().BeEquivalentTo(
expectedOExpressionValidationException);

this.expressionBrokerMock.Verify(broker =>
broker.ApplyExpression<object>(
It.IsAny<IQueryable<object>>(),
It.IsAny<Expression>()),
Times.Never);

this.expressionBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowValidationExceptionOnApplyIfExpressionIsNull()
{
// given
OExpression randomOExpression = CreateRandomOExpression();
IQueryable<object> someSource = CreateRandomSource();
OExpression invalidOExpression = randomOExpression;
invalidOExpression.Expression = null;

var invalidOExpressionException =
new InvalidOExpressionException();

invalidOExpressionException.AddData(
key: nameof(OExpression.Expression),
values: "Value is required");

var expectedOExpressionValidationException =
new OExpressionValidationException(
invalidOExpressionException);

// when
Action applyExpressionAction = () =>
this.oExpressionService.ApplyExpression(
someSource,
invalidOExpression);

OExpressionValidationException actualOExpressionValidationException =
Assert.Throws<OExpressionValidationException>(
applyExpressionAction);

// then
actualOExpressionValidationException.Should().BeEquivalentTo(
expectedOExpressionValidationException);

this.expressionBrokerMock.Verify(broker =>
broker.ApplyExpression<object>(
It.IsAny<IQueryable<object>>(),
It.IsAny<Expression>()),
Times.Never);

this.expressionBrokerMock.VerifyNoOtherCalls();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
using System.Collections.Immutable;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Scripting;
using Moq;
Expand Down Expand Up @@ -51,6 +50,31 @@ public static TheoryData<Exception> DependencyExceptions()
};
}

public static TheoryData<Exception> ApplyDependencyExceptions()
{
var someInnerException = new Exception();

return new TheoryData<Exception>
{
new TargetException(),
new TargetParameterCountException(),
new MethodAccessException(),
new TargetInvocationException(someInnerException),
new NotSupportedException()
};
}

public static TheoryData<Exception> ApplyDependencyValidationExceptions()
{
return new TheoryData<Exception>
{
new InvalidCastException(),
new ArgumentNullException(),
new ArgumentOutOfRangeException(),
new InvalidOperationException()
};
}

private static (List<OToken>, string) CreateRandomPropertyOTokens()
{
var randomOTokens = new List<OToken>();
Expand Down Expand Up @@ -108,7 +132,7 @@ private static T GetEnumThatIsNot<T>(T notThisValue) where T : Enum

int randomNumber = new Random()
.Next(
minValue: 0,
minValue: 0,
maxValue: allValues.Length);

return allValues[randomNumber];
Expand All @@ -123,6 +147,18 @@ private static int GetRandomNumber() =>
private static string CreateRandomString() =>
new MnemonicString().GetValue();

private static IQueryable<object> CreateRandomSource()
{
var filler = new Filler<object>();

filler.Setup()
.OnType<object>().Use(CreateRandomString());

return filler
.Create(count: GetRandomNumber())
.AsQueryable<object>();
}

private static Filler<OExpression> CreateOExpressionFiller()
{
var filler = new Filler<OExpression>();
Expand Down
Loading
Loading