public void GivenSerializeWhenCalledWithNullExpressionThenShouldThrowArgumentNull() { Expression expression = null; Assert.Throws <ArgumentNullException>(() => QueryExprSerializer.Serialize(expression)); }
public void MultipleSelectManyProjectionWorks() { var dataQuery = TestableThing.MakeQuery(5); IQueryable <Tuple <string, string, string> > SelectMany(IQueryable <TestableThing> query) => query.SelectMany(t => t.ChildThings, (t, c) => new { parentId = t.Id, childId = c.Id, children = c.ChildThings }).SelectMany(tc => tc.children, (tc, tcc) => new { tc.parentId, tc.childId, grandChildId = tcc.Id }).Select(t => Tuple.Create(t.parentId, t.childId, t.grandChildId)); var query = SelectMany(IQueryableExtensions.CreateQueryTemplate <TestableThing>()); var root = QueryExprSerializer.Serialize(query); var json = wrapper.FromSerializationRoot(root); // make sure we're not just pulling from the cache var deserializedRoot = wrapper.ToSerializationRoot(json); var newQuery = QueryExprSerializer.DeserializeQuery <Tuple <string, string, string> >(deserializedRoot, dataQuery); var expected = SelectMany(dataQuery).ToList(); var actual = newQuery.ToList(); Assert.NotNull(actual); Assert.Equal(expected, actual); }
public void GivenSerializeWhenCalledWithNullQueryThenShouldThrowArgumentNull() { IQueryable query = null; Assert.Throws <ArgumentNullException>(() => QueryExprSerializer.Serialize(query)); }
/// <summary> /// Deserializes the query. /// </summary> /// <param name="template">The <see cref="IQueryable"/> to run.</param> /// <param name="json">The stream with json info.</param> /// <param name="logger">The logger.</param> /// <returns>The <see cref="IQueryable"/> result.</returns> public async Task <QueryResult> DeserializeAsync( IQueryable template, Stream json, ILogger logger = null) { Ensure.NotNull(() => template); Ensure.NotNull(() => json); var request = await JsonSerializer.DeserializeAsync <SerializationPayload>(json); Ensure.VariableNotNull(() => request); Ensure.NotNullOrWhitespace(() => request.Json); if (logger != null) { logger.LogInformation($"Query payload: {request.Json}"); } var options = jsonOptions.Value(); var root = jsonSerializer.Value.ToSerializationRoot(request.Json, options); var query = QueryExprSerializer.DeserializeQuery(template, root); if (logger != null) { logger.LogInformation($"Deserialized query: {query.Expression}"); } return(new QueryResult { Query = query, QueryType = request.GetQueryType(), }); }
public void GivenQueryWhenSerializeCalledThenShouldDeserialize( IQueryable query, Queries type) { var json = QueryExprSerializer.Serialize(query); // make sure we're not just pulling from the cache Reset(); IQueryable queryHost = TestableThing.MakeQuery(10); var newQuery = QueryExprSerializer.DeserializeQuery(queryHost, json); // can't do equivalency check for anonymous types if (!query.AsEnumerableExpression().OfType <NewExpression>() .Any(t => t.Type.IsAnonymousType())) { Assert.True(query.IsEquivalentTo(newQuery)); } if (newQuery is IQueryable <ExpandoObject> anonymousQuery) { var list = anonymousQuery.ToList(); Assert.NotNull(list); } else if (newQuery is IQueryable <TestableThing> thingQuery) { var list = thingQuery.ToList(); ValidateQuery(list, type); } }
public JsonWrapperTests() { QueryExprSerializer.ConfigureRules(rules => rules.RuleForType <QueryExprSerializerTests>() .RuleForType <TestableThing>() .RuleForType(typeof(Tuple))); }
private string queryJson( bool isCount = false, bool useProduct = false, bool isSingle = false) => JsonSerializer.Serialize( new SerializationPayload(isCount ? PayloadType.Count : (isSingle ? PayloadType.Single : PayloadType.Array)) { Json = jsonWrapper.FromSerializationRoot( QueryExprSerializer.Serialize(altQuery ?? (useProduct ? productsQuery : query))) });
private void Reset() { ServiceHost.GetService <IMemberAdapter>().Reset(); QueryExprSerializer.ConfigureRules( rules => rules.RuleForType <QueryExprSerializerTests>() .RuleForType <TestableThing>() .RuleForType <BinarySerializerTests>() .RuleForType(typeof(KeyValuePair)) .RuleForType(typeof(Tuple))); }
public void DeserializeWithConfigurationUsesConfiguration() { var expr = 42.AsConstantExpression(); var serialized = QueryExprSerializer.Serialize(expr); var deserialized = QueryExprSerializer.Deserialize( serialized, null, config => config.CompressExpressionTree(false), null); Assert.NotNull(deserialized); }
public void GivenQueryCanSerializeAndDeserialize(IQueryable query, QueryExprSerializerTests.Queries queryType) { var root = QueryExprSerializer.Serialize(query, config => config.CompressExpressionTree(false)); var json = wrapper.FromSerializationRoot(root); var deserializedRoot = wrapper.ToSerializationRoot(json); Assert.NotNull(deserializedRoot); IQueryable queryHost = TestableThing.MakeQuery(10); var deserializedQuery = QueryExprSerializer.DeserializeQuery(queryHost, deserializedRoot); Assert.NotNull(deserializedQuery); Assert.True(query.Expression.IsEquivalentTo(deserializedQuery.Expression)); }
public void GivenQueryWhenSerializeCalledThenShouldDeserializeForType( IQueryable <TestableThing> query, Queries type) { var json = QueryExprSerializer.Serialize(query); Reset(); var queryHost = TestableThing.MakeQuery(100); var newQuery = QueryExprSerializer.DeserializeQuery <TestableThing>(json, queryHost); Assert.True(query.IsEquivalentTo(newQuery)); ValidateQuery(newQuery.ToList(), type); }
public void HandlesElementInits() { Expression <Func <DataHost> > elemInit = () => new DataHost { Elems = { new DataElem() } }; var root = QueryExprSerializer.Serialize(elemInit, config => config.CompressExpressionTree(false)); var json = wrapper.FromSerializationRoot(root); var deserializedRoot = wrapper.ToSerializationRoot(json); QueryExprSerializer.ConfigureRules(rules => rules.RuleForType <DataHost>() .RuleForType <DataElem>()); var deserializedExpr = QueryExprSerializer.Deserialize <LambdaExpression>(deserializedRoot); Assert.True(elemInit.IsEquivalentTo(deserializedExpr)); }
public void HandlesNullAnonymousTypes() { var expected = new { Id = 1, SubAnon = default(object) }; var expr = expected.AsConstantExpression(); var root = QueryExprSerializer.Serialize(expr); var json = wrapper.FromSerializationRoot(root); var deserializedRoot = wrapper.ToSerializationRoot(json); var deserializedExpr = QueryExprSerializer.Deserialize <ConstantExpression>(deserializedRoot); Assert.True(expressionEvaluator.Value.AnonymousValuesAreEquivalent(expr.Value, deserializedExpr.Value)); }
public void HandlesInterfaces() { var expr = Expression.Constant(new IdContainer { Id = Guid.NewGuid().ToString(), Name = nameof(IdContainer), }, typeof(IHaveId)); var root = QueryExprSerializer.Serialize(expr, config => config.CompressExpressionTree(false)); var json = wrapper.FromSerializationRoot(root); var deserializedRoot = wrapper.ToSerializationRoot(json); var deserializedExpr = QueryExprSerializer.Deserialize <ConstantExpression>(deserializedRoot); Assert.Equal(typeof(IHaveId), deserializedExpr.Type); Assert.True(deserializedExpr.Value is IdContainer); Assert.Equal(nameof(IdContainer), ((IdContainer)deserializedExpr.Value).Name); }
public void GivenRulesPassedWhenMapPowerToolsEFCoreBaseCalledThenShouldConfigureRules() { IEndpointRouteBuilder builder = null; CreateSimpleServer(config => builder = config); builder.MapPowerToolsEFCore( routePattern, defaultTypes, rules => rules.RuleForType <MiddlewareExtensionsTests>()); var engine = ServiceHost.GetService <IRulesEngine>(); Assert.True(engine.MemberIsAllowed(typeof(MiddlewareExtensionsTests))); // reset rules QueryExprSerializer.ConfigureRules(); }
public void SerializesAndDeserializesAnonymousTypes() { var expected = new { Id = 1, SubAnon = new { Id = 2, Two = 2.ToString() } }; var expr = expected.AsConstantExpression(); var root = QueryExprSerializer.Serialize(expr); var json = wrapper.FromSerializationRoot(root); var deserializedRoot = wrapper.ToSerializationRoot(json); var deserializedExpr = QueryExprSerializer.Deserialize <ConstantExpression>(deserializedRoot); Assert.True(expressionEvaluator.Value.AnonymousValuesAreEquivalent(expr.Value, deserializedExpr.Value)); }
public void NewArrayExpressionShouldDeserialize() { var newArray = Expression.NewArrayInit( typeof(int), Expression.Constant(1), Expression.Constant(2)); Func <IConfigurationBuilder, IConfigurationBuilder> config = builder => builder.CompressTypes(false).CompressExpressionTree(false); var expr = QueryExprSerializer.Serialize(newArray, cfg => config(cfg)); var state = config(ServiceHost.GetService <IConfigurationBuilder>()).Configure(); var deserialized = serializer.Deserialize(expr.Expression as NewArray, state); Assert.Equal(newArray.Type, deserialized.Type); Assert.Equal( newArray.Expressions.OfType <ConstantExpression>().Select(ce => ce.Value), deserialized.Expressions.OfType <ConstantExpression>().Select(ce => ce.Value)); }
/// <summary> /// Entry point. /// </summary> /// <param name="args">Arguments passed in.</param> /// <returns>A <see cref="Task"/> for asychronous processing.</returns> public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add <App>("app"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); // this adds the client with the base address to post to /efcore/{context}/{collection} builder.Services.AddExpressionPowerToolsEFCore(new Uri(builder.HostEnvironment.BaseAddress)); if (builder.HostEnvironment.IsDevelopment()) { QueryExprSerializer.ConfigureDefaults(config => config.CompressTypes(false)); } // this adds a helper class for composing the query builder.Services.AddScoped( sp => new RemoteQueryClientService()); await builder.Build().RunAsync(); }
public BinarySerializerTests() { QueryExprSerializer.ConfigureRules(config => config.RuleForType <BinarySerializerTests>()); }
private string queryJson() => JsonSerializer.Serialize( new SerializationPayload { Json = jsonWrapper.FromSerializationRoot(QueryExprSerializer.Serialize(query)) });
public QueryExprSerializerTests() { QueryExprSerializer.ConfigureDefaults( config => config.CompressExpressionTree(false)); }
public void AlternateSelectManyWorks() { QueryExprSerializer.ConfigureRules( rules => rules.RuleForType <RelatedThing>()); var db = typeof(JsonWrapperTests).Assembly.GetTypes() .Select(t => new MockType { Id = t.ToString(), Name = t.FullName, Methods = t.GetMethods().Select( m => new MockMethod { Id = m.ToString(), Name = m.Name, Parameters = m.GetParameters() .Select(p => new MockParameter { Id = $"{p.Position}-{p.ParameterType}", Name = p.Name, }).ToList() }).ToList() }); Func <IQueryable <MockType>, IQueryable <RelatedThing> > makeQuery = q => q .Where(t => t.Name != null) .SelectMany( t => t.Methods, (t, m) => new { t.Name, MethodName = m.Name, m.Parameters, }) .SelectMany( tm => tm.Parameters, (tm, p) => new RelatedThing { TypeName = tm.Name, MethodName = tm.MethodName, ParameterName = p.Name, }) .OrderBy(r => r.TypeName) .ThenBy(r => r.MethodName) .ThenBy(r => r.ParameterName); var queryToSerialize = makeQuery(new List <MockType>().AsQueryable()); var root = QueryExprSerializer.Serialize(queryToSerialize); var json = wrapper.FromSerializationRoot(root); var deserializedRoot = wrapper.ToSerializationRoot(json); var newQuery = QueryExprSerializer.DeserializeQuery <RelatedThing>(deserializedRoot, db.AsQueryable()); var result = makeQuery(db.AsQueryable()); var expected = result.ToList(); var actual = newQuery.ToList(); Assert.NotNull(actual); Assert.Equal(expected.Count(), actual.Count()); }
private string GetJson(bool isCount = false) => JsonSerializer.Serialize( new SerializationPayload(isCount ? PayloadType.Count : PayloadType.Array) { Json = jsonWrapper.FromSerializationRoot(QueryExprSerializer.Serialize(query)), });
/// <summary> /// Main configuration method for Power Tools EF Core middleware. /// </summary> /// <param name="endpointRouteBuilder">The <see cref="IEndpointRouteBuilder"/>.</param> /// <param name="pattern">The pattern for the route (defaults to <c>/efcore</c>).</param> /// <param name="dbContextTypes">The list of <c>DbContext</c> types to support.</param> /// <param name="rules">The <see cref="IRulesConfiguration"/> to configure serialization rules.</param> /// <param name="noDefaultRules">Determines whether the default rule set should be applied.</param> /// <param name="options">The <see cref="IConfigurationBuilder"/> to configure options.</param> /// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns> public static IEndpointConventionBuilder MapPowerToolsEFCore( this IEndpointRouteBuilder endpointRouteBuilder, RoutePattern pattern, Type[] dbContextTypes, Action <IRulesConfiguration> rules = null, bool noDefaultRules = false, Action <IConfigurationBuilder> options = null) { Ensure.NotNull(() => endpointRouteBuilder); Ensure.NotNull(() => pattern); Ensure.NotNull(() => dbContextTypes); if (pattern.Parameters.Count != 2) { throw new ArgumentException( $"{DefaultPattern}<~>{pattern.RawText}", nameof(pattern)); } if (!pattern.Parameters.Any(p => p.Name == Context)) { throw new ArgumentException(Context, nameof(pattern)); } if (!pattern.Parameters.Any(p => p.Name == Collection)) { throw new ArgumentException(Collection, nameof(pattern)); } if (dbContextTypes.Length == 0) { throw new ArgumentException( $"{nameof(dbContextTypes)}.Length = 0", nameof(dbContextTypes)); } var badType = dbContextTypes.FirstOrDefault( t => !typeof(DbContext).IsAssignableFrom(t)); if (badType != null) { throw new ArgumentException( $"{badType} != {typeof(DbContext)}", nameof(dbContextTypes)); } // passed tests, check configuration if (options != null) { QueryExprSerializer.ConfigureDefaults(options); } if (rules != null || noDefaultRules == true) { QueryExprSerializer.ConfigureRules(rules, noDefaultRules); } var appBuilder = endpointRouteBuilder.CreateApplicationBuilder(); appBuilder.UseMiddleware <ExpressionPowerToolsEFCoreMiddleware>( pattern.RawText, dbContextTypes); return(endpointRouteBuilder.Map(pattern, appBuilder.Build()) .WithDisplayName($"Expression Power Tools Serialization Pipeline")); }