public void MultipleSelectManyProjectionWorks() { Reset(); 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 json = Serializer.Serialize(query); // make sure we're not just pulling from the cache Reset(); var newQuery = Serializer.DeserializeQuery <Tuple <string, string, string> >(json, dataQuery); var expected = SelectMany(dataQuery).ToList(); var actual = newQuery.ToList(); Assert.NotNull(actual); Assert.Equal(expected, actual); }
public void GivenQueryWhenSerializeCalledThenShouldDeserialize( IQueryable query, Queries type) { var json = Serializer.Serialize(query); // make sure we're not just pulling from the cache Reset(); IQueryable queryHost = TestableThing.MakeQuery(10); var newQuery = Serializer.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 void GivenLambdaWithAnonymousReturnTypeWhenTransformCalledThenShouldReturnExpression(LambdaExpression lambda) { var actual = adapter.TransformLambda(lambda); Assert.NotSame(lambda, actual); object source, target; if (lambda.Parameters.Any()) { var thing = new TestableThing(); target = actual.Compile().DynamicInvoke(thing); source = lambda.Compile().DynamicInvoke(thing); } else { target = actual.Compile().DynamicInvoke(null); source = lambda.Compile().DynamicInvoke(null); } object targetVal; if (lambda.AsEnumerable().OfType <NewExpression>().Any()) { Assert.IsType <AnonInitializer>(target); targetVal = (target as AnonInitializer).AnonValue.GetValue(); } else { targetVal = target; } Assert.True(ExpressionEquivalency.ValuesAreEquivalent(source, targetVal)); }
public void GivenDefaultConfigurationWhenNoConfigProvidedThenShouldUseDefault(bool configOverride) { var query = TestableThing.MakeQuery().Where(t => t.Id.Contains("aa") && (t.IsActive || t.Value < int.MaxValue / 2)); Serializer.ConfigureDefaults(config => config.WithJsonSerializerOptions( new JsonSerializerOptions { IgnoreNullValues = false, IgnoreReadOnlyProperties = true }).Configure()); if (configOverride) { var json = Serializer.Serialize(query, config => config.CompressTypes(false).Configure()); Assert.DoesNotContain("null", json); Assert.DoesNotContain("^", json); Reset(); var expr = Serializer.DeserializeQuery <TestableThing>(json, config: config => config.CompressTypes(false).Configure()); Assert.True(query.IsEquivalentTo(expr)); } else { var json = Serializer.Serialize(query); Assert.Contains("null", json); // Assert.Contains("^", json); } Serializer.ConfigureDefaults(config => config.Configure()); }
public void GivenQueryWhenSerializeCalledThenShouldDeserialize( IQueryable query, Queries type) { var json = Serializer.Serialize(query); // make sure we're not just pulling from the cache Reset(); rulesConfig.Value.RuleForType <TestableThing>() .RuleForType <SerializerTests>(); IQueryable queryHost = TestableThing.MakeQuery(100); var newQuery = Serializer.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)); } var testRun = newQuery.AsObjectArray(); // ensure it runs Assert.NotNull(testRun); if (newQuery is IQueryable <TestableThing> thingQuery) { var list = thingQuery.ToList(); ValidateQuery(list, type); } }
public void GivenNestedMethodsThenWillCompress() { var str = "aa "; var query = TestableThing.MakeQuery().Where(t => t.Id.Contains(str.Trim())); var expression = target.EvalAndCompress(query.Expression); Assert.Contains(expression.AsEnumerable().ConstantsOfType <string>(), ce => ce.Value.ToString() == str.Trim()); }
public void GivenFilterWithVariableWhenVisitedThenExtractsValues() { var isActive = true; var query = TestableThing.MakeQuery().Where(t => t.IsActive == isActive); var expression = target.EvalAndCompress(query.Expression); Assert.Contains(expression.AsEnumerable().OfType <ConstantExpression>(), ce => ce.Type == typeof(bool) && (bool)ce.Value == true); }
public void GivenExpressionThatCanResolveWhenVisitedThenExtractsValues() { var x = 2; var y = 3; var query = TestableThing.MakeQuery().Where(t => (x < y) ? t.IsActive : !t.IsActive); var expression = target.EvalAndCompress(query.Expression); Assert.DoesNotContain(expression.AsEnumerable(), ex => ex is ConditionalExpression); }
public void GivenExpressionAgainstStringAndDateWhenVisitedWillCompress() { var days = 5; var str = "aa"; var query = TestableThing.MakeQuery().Where(t => t.Created > DateTime.Now.AddDays(-1 * days) && t.Id.Contains(str)); var expression = target.EvalAndCompress(query.Expression); Assert.Contains(expression.AsEnumerable().ConstantsOfType <string>(), ce => ce.Value.ToString() == str); }
public void GivenSkipOrTakeWithVariableWhenVisitedThenExtractsConstants() { var skip = 1; var take = 2; var query = TestableThing.MakeQuery().Skip(skip).Take(take); var expression = target.EvalAndCompress(query.Expression); Assert.Contains(expression.AsEnumerable().OfType <ConstantExpression>(), ce => ce.Type == typeof(int) && (int)ce.Value == skip); Assert.Contains(expression.AsEnumerable().OfType <ConstantExpression>(), ce => ce.Type == typeof(int) && (int)ce.Value == take); }
public void GivenObjectWhenLambdaExpressionThatReferencesPropertyIsDeserializedThenShouldResolveProperty() { var things = TestableThing.MakeQuery(2).ToList(); Expression <Func <List <TestableThing>, string> > firstId = list => list.First().Id; var serialized = TestSerializer.GetSerializedFragment <Lambda, LambdaExpression>(firstId); var deserialized = lambdaSerializer.Deserialize(serialized, new SerializationState()); var expected = firstId.Compile()(things); var actual = deserialized.Compile().DynamicInvoke(things); Assert.Equal(expected, actual); }
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 static IEnumerable <object[]> GetQueryMatrix() { yield return(new object[] { TestableThing.MakeQuery().Skip(1).Take(1), Queries.Skip1Take1 }); yield return(new object[] { TestableThing.MakeQuery().OrderBy(t => t.Created).ThenByDescending(t => t.Id), Queries.OrderByCreatedThenByDescendingId }); yield return(new object[] { TestableThing.MakeQuery().Where(t => t.Id.Contains("aa")), Queries.WhereIdContainsAA }); yield return(new object[] { TestableThing.MakeQuery().Where(t => Property <int>(t, nameof(TestableThing.Value)) > 500), Queries.CustomGenericProperty }); yield return(new object[] { TestableThing.MakeQuery().Select(t => t.Id), Queries.IdProjection }); yield return(new object[] { TestableThing.MakeQuery().Select(t => new { t.Id }), Queries.IdAnonymousType }); yield return(new object[] { TestableThing.MakeQuery().OrderBy(t => t.Id).Select(t => new TestableThing(t.Id)), Queries.IdOnly }); yield return(new object[] { TestableThing.MakeQuery().Where(t => t.Id.Contains("aa") && (t.IsActive || t.Value < int.MaxValue / 2)), Queries.Filtered }); }
public void GivenQueryWhenSerializeCalledThenShouldDeserializeForType( IQueryable <TestableThing> query, Queries type) { var json = Serializer.Serialize(query); Reset(); var queryHost = TestableThing.MakeQuery(100); var newQuery = Serializer.DeserializeQuery <TestableThing>(json, queryHost); Assert.True(query.IsEquivalentTo(newQuery)); ValidateQuery(newQuery.ToList(), type); }
public void GivenNewExpressionWithAnonymousTypeAndReferenceWhenTransformNewCalledThenShouldReturnTransformedExpression() { var thing = new TestableThing(); var query = new List <TestableThing>().AsQueryable(); var projection = query.Select(t => new { t.Id }); var exprNew = projection.Expression.AsEnumerable().OfType <NewExpression>().Single(); var parameters = projection.Expression.AsEnumerable().OfType <LambdaExpression>() .Single().Parameters; var transformed = adapter.TransformNew(exprNew); Assert.Equal(typeof(AnonInitializer), transformed.Type); var originalNew = Expression.Lambda <Func <TestableThing, object> >(exprNew, parameters); var originalObj = originalNew.Compile()(thing); var transformedNew = Expression.Lambda <Func <TestableThing, AnonInitializer> >(transformed, parameters); var transformedObj = transformedNew.Compile()(thing).AnonValue.GetValue(); Assert.True(ExpressionEquivalency.ValuesAreEquivalent(originalObj, transformedObj)); }
public void GivenConditionalIfTestCanBeEvaluatedThenShouldTransformToTestResult(int scenario) { if (scenario == 0 || scenario == 1) { var x = scenario == 0 ? 2 : 3; var expected = scenario == 0 ? 0 : 1; Expression <Func <int> > expr = () => x % 2 == 0 ? 0 : 1; var compiled = target.EvalAndCompress(expr); Assert.False(compiled.AsEnumerable().OfType <ConditionalExpression>().Any()); var actual = ((Func <int>)((ConstantExpression)compiled).Value)(); Assert.Equal(expected, actual); } else { var query = TestableThing.MakeQuery().Select(t => t.Created < DateTime.Now.AddDays(-7) ? 0 : 1); var compiledQuery = target.EvalAndCompress(query.Expression); Assert.True(compiledQuery.AsEnumerable().OfType <ConditionalExpression>().Any()); } }
public void GivenConvertedLambdaWhenTransformCalledThenShouldReturnExpression(LambdaExpression lambda) { var transformed = adapter.TransformLambda(lambda); var actual = adapter.TransformLambda(transformed); object source, target; if (lambda.Parameters.Any()) { var thing = new TestableThing(); target = actual.Compile().DynamicInvoke(thing); source = lambda.Compile().DynamicInvoke(thing); } else { target = actual.Compile().DynamicInvoke(null); source = lambda.Compile().DynamicInvoke(null); } Assert.True(ExpressionEquivalency.ValuesAreEquivalent(source, target)); }
public void GroupByWorks() { Reset(); var dataQuery = TestableThing.MakeQuery(10);
public static IEnumerable <object[]> GetQueryMatrix() { yield return(new object[] { TestableThing.MakeQuery().Select(t => new { t.Id }), Queries.IdAnonymousType }); yield return(new object[] { TestableThing.MakeQuery().SelectMany(t => t.ChildThings), Queries.SelectMany }); yield return(new object[] { TestableThing.MakeQuery().Where(t => t.ChildThings.Count > 2).Select(t => new TestableThing(t.Id) { ChildThings = { new TestableThing { Id = Guid.NewGuid().ToString() }, new TestableThing { Id = t.ChildThings[0].Id } } }), Queries.MemberInit }); yield return(new object[] { TestableThing.MakeQuery().Skip(1).Take(1), Queries.Skip1Take1 }); yield return(new object[] { TestableThing.MakeQuery().OrderBy(t => t.Created).ThenByDescending(t => t.Id), Queries.OrderByCreatedThenByDescendingId }); yield return(new object[] { TestableThing.MakeQuery().Where(t => t.Id.Contains("aa")), Queries.WhereIdContainsAA }); yield return(new object[] { TestableThing.MakeQuery().Where(t => Property <int>(t, nameof(TestableThing.Value)) > 500), Queries.CustomGenericProperty }); yield return(new object[] { TestableThing.MakeQuery().Select(t => t.Id), Queries.IdProjection }); yield return(new object[] { TestableThing.MakeQuery().OrderBy(t => t.Id).Select(t => new TestableThing(t.Id)), Queries.IdOnly }); yield return(new object[] { TestableThing.MakeQuery().Where(t => t.Id.Contains("aa") && (t.IsActive || t.Value < int.MaxValue / 2)), Queries.Filtered }); yield return(new object[] { TestableThing.MakeQuery().Where(t => t.Id.Contains("aa")).Select(t => new TestableThing { Id = t.Id }), Queries.MemberInit }); yield return(new object[] { TestableThing.MakeQuery().Select(t => new TestableThing(t.Id) { Data = { Data = t.ChildThings.Count.ToString() } }), Queries.MemberInit }); }
public void WhenDeserializeQueryForTypeCalledWithEmptyOrNullJsonThenShouldThrowArgument(string json) { Assert.Throws <ArgumentException>(() => Serializer.DeserializeQuery(TestableThing.MakeQuery(), json)); }
public static IEnumerable <object[]> GetAndMatrix() { var core = TestableThing.MakeQuery(); Expression <Func <bool> > eval = () => DateTime.Now.Ticks < 12;