Add basic Translator tests to Connected.Data.Tests
This commit is contained in:
parent
bdbb99e17b
commit
08e5857fc8
@ -41,6 +41,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connected.Validation", "src
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connected.Expressions", "src\Connected.Expressions\Connected.Expressions.csproj", "{E597528B-95CA-4ACB-A44B-2C0737084581}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connected.Expressions", "src\Connected.Expressions\Connected.Expressions.csproj", "{E597528B-95CA-4ACB-A44B-2C0737084581}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Connected.Data.Tests", "src\Connected.Data.Tests\Connected.Data.Tests.csproj", "{C6520F60-774E-41B1-8B17-7EF0B825BF6A}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D6F579A8-2BDD-4E47-BF39-FB8650E5039E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Connected.Expressions.Tests", "src\Connected.Expressions.Tests\Connected.Expressions.Tests.csproj", "{9D4ED240-112A-467D-BCD7-2989DD172B83}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -123,10 +129,22 @@ Global
|
|||||||
{E597528B-95CA-4ACB-A44B-2C0737084581}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{E597528B-95CA-4ACB-A44B-2C0737084581}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E597528B-95CA-4ACB-A44B-2C0737084581}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{E597528B-95CA-4ACB-A44B-2C0737084581}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E597528B-95CA-4ACB-A44B-2C0737084581}.Release|Any CPU.Build.0 = Release|Any CPU
|
{E597528B-95CA-4ACB-A44B-2C0737084581}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C6520F60-774E-41B1-8B17-7EF0B825BF6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6520F60-774E-41B1-8B17-7EF0B825BF6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C6520F60-774E-41B1-8B17-7EF0B825BF6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C6520F60-774E-41B1-8B17-7EF0B825BF6A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9D4ED240-112A-467D-BCD7-2989DD172B83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9D4ED240-112A-467D-BCD7-2989DD172B83}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9D4ED240-112A-467D-BCD7-2989DD172B83}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9D4ED240-112A-467D-BCD7-2989DD172B83}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{C6520F60-774E-41B1-8B17-7EF0B825BF6A} = {D6F579A8-2BDD-4E47-BF39-FB8650E5039E}
|
||||||
|
{9D4ED240-112A-467D-BCD7-2989DD172B83} = {D6F579A8-2BDD-4E47-BF39-FB8650E5039E}
|
||||||
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {C63B5A75-C99A-45D7-A691-26E568A51740}
|
SolutionGuid = {C63B5A75-C99A-45D7-A691-26E568A51740}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
28
src/Connected.Data.Tests/Connected.Data.Tests.csproj
Normal file
28
src/Connected.Data.Tests/Connected.Data.Tests.csproj
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Storage\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Connected.Data\Connected.Data.csproj" />
|
||||||
|
<ProjectReference Include="..\Connected.Entities\Connected.Entities.csproj" />
|
||||||
|
<ProjectReference Include="..\Connected.Expressions\Connected.Expressions.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
134
src/Connected.Data.Tests/Translation/TranslatorTests.cs
Normal file
134
src/Connected.Data.Tests/Translation/TranslatorTests.cs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Connected.Expressions;
|
||||||
|
using Connected.Data.Sql;
|
||||||
|
using Connected.Expressions.Translation;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using Connected.Data.Storage;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using Connected.Entities;
|
||||||
|
|
||||||
|
namespace Connected.Data.Tests.Translation;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class TranslatorTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void Translator_GeneratesBasicSelectExpression_UsingTSQL()
|
||||||
|
{
|
||||||
|
var context = new ExpressionCompilationContext(new TSqlLanguage());
|
||||||
|
|
||||||
|
var translator = new Translator(context);
|
||||||
|
|
||||||
|
var data = SampleData.All();
|
||||||
|
|
||||||
|
var dataQueryable = data.AsQueryable();
|
||||||
|
|
||||||
|
var query = (from x in dataQueryable select x);
|
||||||
|
|
||||||
|
var operatorMethodInfo = QueryableMethods.SingleOrDefaultWithoutPredicate;
|
||||||
|
|
||||||
|
if (operatorMethodInfo.IsGenericMethod)
|
||||||
|
{
|
||||||
|
operatorMethodInfo = operatorMethodInfo.GetGenericArguments().Length == 2
|
||||||
|
? operatorMethodInfo.MakeGenericMethod(typeof(DummyEntity), typeof(DummyEntity).GetGenericArguments().Single())
|
||||||
|
: operatorMethodInfo.MakeGenericMethod(typeof(DummyEntity));
|
||||||
|
}
|
||||||
|
|
||||||
|
var expr = Expression.Call(instance: null, method: operatorMethodInfo, arguments: new[] { query.Expression });
|
||||||
|
|
||||||
|
var result = translator.Translate(expr) as ProjectionExpression;
|
||||||
|
|
||||||
|
var select = result.Select;
|
||||||
|
|
||||||
|
Assert.IsInstanceOfType(select, typeof(SelectExpression));
|
||||||
|
Assert.IsInstanceOfType(select.From, typeof(TableExpression));
|
||||||
|
Assert.IsNull(select.Where, "Where should be null");
|
||||||
|
Assert.IsNull(select.Take, "Take should be null");
|
||||||
|
Assert.IsNull(select.Skip, "Skip should be null");
|
||||||
|
Assert.AreEqual(0, select.GroupBy.Count);
|
||||||
|
Assert.IsFalse(select.IsReverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Translator_GeneratesSelectExpression_WithWhere_UsingTSQL()
|
||||||
|
{
|
||||||
|
var context = new ExpressionCompilationContext(new TSqlLanguage());
|
||||||
|
|
||||||
|
var translator = new Translator(context);
|
||||||
|
|
||||||
|
var data = SampleData.All();
|
||||||
|
|
||||||
|
var dataQueryable = data.AsQueryable();
|
||||||
|
|
||||||
|
var query = (from x in dataQueryable where x.Id == 1 select x);
|
||||||
|
|
||||||
|
var operatorMethodInfo = QueryableMethods.SingleOrDefaultWithoutPredicate;
|
||||||
|
|
||||||
|
if (operatorMethodInfo.IsGenericMethod)
|
||||||
|
{
|
||||||
|
operatorMethodInfo = operatorMethodInfo.GetGenericArguments().Length == 2
|
||||||
|
? operatorMethodInfo.MakeGenericMethod(typeof(DummyEntity), typeof(DummyEntity).GetGenericArguments().Single())
|
||||||
|
: operatorMethodInfo.MakeGenericMethod(typeof(DummyEntity));
|
||||||
|
}
|
||||||
|
|
||||||
|
var expr = Expression.Call(instance: null, method: operatorMethodInfo, arguments: new[] { query.Expression });
|
||||||
|
|
||||||
|
var result = translator.Translate(expr) as ProjectionExpression;
|
||||||
|
|
||||||
|
var select = result.Select;
|
||||||
|
|
||||||
|
Assert.IsInstanceOfType(select, typeof(SelectExpression));
|
||||||
|
Assert.IsInstanceOfType(select.From, typeof(TableExpression));
|
||||||
|
Assert.IsNotNull(select.Where, "Where should not be null");
|
||||||
|
Assert.IsNull(select.Take, "Take should be null");
|
||||||
|
Assert.IsNull(select.Skip, "Skip should be null");
|
||||||
|
Assert.AreEqual(0, select.GroupBy.Count);
|
||||||
|
Assert.IsFalse(select.IsReverse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record DummyEntity : Entity<long>;
|
||||||
|
|
||||||
|
internal static class SampleData
|
||||||
|
{
|
||||||
|
public static List<DummyEntity> All()
|
||||||
|
{
|
||||||
|
return new List<DummyEntity>
|
||||||
|
{
|
||||||
|
new DummyEntity{ Id = 1},
|
||||||
|
new DummyEntity{ Id = 2},
|
||||||
|
new DummyEntity{ Id = 3},
|
||||||
|
new DummyEntity{ Id = 4},
|
||||||
|
new DummyEntity{ Id = 5}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class QueryableMethods
|
||||||
|
{
|
||||||
|
static QueryableMethods()
|
||||||
|
{
|
||||||
|
var queryableMethodGroups = typeof(Queryable)
|
||||||
|
.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
|
||||||
|
.GroupBy(mi => mi.Name)
|
||||||
|
.ToDictionary(e => e.Key, l => l.ToList());
|
||||||
|
|
||||||
|
SingleWithoutPredicate = GetMethod(nameof(Queryable.Single), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
|
||||||
|
SingleOrDefaultWithoutPredicate = GetMethod(nameof(Queryable.SingleOrDefault), 1, types => new[] { typeof(IQueryable<>).MakeGenericType(types[0]) });
|
||||||
|
|
||||||
|
MethodInfo GetMethod(string name, int genericParameterCount, Func<Type[], Type[]> parameterGenerator)
|
||||||
|
{
|
||||||
|
return queryableMethodGroups[name].Single(mi => ((genericParameterCount == 0 && !mi.IsGenericMethod)
|
||||||
|
|| (mi.IsGenericMethod && mi.GetGenericArguments().Length == genericParameterCount))
|
||||||
|
&& mi.GetParameters().Select(e => e.ParameterType).SequenceEqual(parameterGenerator(mi.IsGenericMethod ? mi.GetGenericArguments() : Array.Empty<Type>())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodInfo SingleWithoutPredicate { get; }
|
||||||
|
public static MethodInfo SingleOrDefaultWithoutPredicate { get; }
|
||||||
|
}
|
1
src/Connected.Data.Tests/Usings.cs
Normal file
1
src/Connected.Data.Tests/Usings.cs
Normal file
@ -0,0 +1 @@
|
|||||||
|
global using Microsoft.VisualStudio.TestTools.UnitTesting;
|
Loading…
x
Reference in New Issue
Block a user