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
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connected.Expressions", "src\Connected.Expressions\Connected.Expressions.csproj", "{E597528B-95CA-4ACB-A44B-2C0737084581}"
|
||||
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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
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
|
||||
SolutionGuid = {C63B5A75-C99A-45D7-A691-26E568A51740}
|
||||
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