From 3c374cae5823971002d8b235dc1a12d252522604 Mon Sep 17 00:00:00 2001 From: Maurycy Markowski Date: Thu, 3 Oct 2019 18:10:38 -0700 Subject: [PATCH] Fix to #17236 - Improve readability of expressions in client evaluation exception Adding a new switch to ExpressionPrinter that creates simplified output for Print and verbose (i.e. what we had before this change) for PrintDebug. Simplified output means: - displaying extension methods as extension methods rather than regular static methods, - simplifying display of Navigation object, - not showing if lambda body references parameter that is out of scope. Also fixed minor display bugs in expression printer. Also some changes in testing: - added unit tests for ExpressionPrinter, - DRY the "translation failed" tests, - "translation failed" tests no longer verify expression in the exception message and instead just make sure that right exception is thrown. --- .../Metadata/Internal/NavigationExtensions.cs | 30 +- src/EFCore/Query/ExpressionPrinter.cs | 101 +++- ...nExpandingExpressionVisitor.Expressions.cs | 3 +- ...terializeCollectionNavigationExpression.cs | 11 +- .../Query/SimpleQueryCosmosTest.cs | 83 +--- .../Query/InheritanceInMemoryTest.cs | 9 +- .../Query/SimpleQueryInMemoryTest.cs | 36 +- .../Query/QueryNoClientEvalTestBase.cs | 170 +++---- .../Query/UdfDbFunctionTestBase.cs | 262 ++++------ .../Query/FiltersTestBase.cs | 4 +- .../Query/GearsOfWarQueryTestBase.cs | 103 ++-- .../Query/IncludeAsyncTestBase.cs | 6 +- .../Query/IncludeTestBase.cs | 20 +- .../Query/QueryNavigationsTestBase.cs | 183 +++---- .../SimpleQueryTestBase.ResultOperators.cs | 171 +++---- .../Query/SimpleQueryTestBase.Select.cs | 15 +- .../Query/SimpleQueryTestBase.Where.cs | 109 ++-- .../Query/SimpleQueryTestBase.cs | 465 ++++++++---------- .../Query/QueryLoggingSqlServerTest.cs | 2 +- .../Query/SimpleQuerySqlServerTest.Select.cs | 8 +- .../BuiltInDataTypesSqliteTest.cs | 77 +-- .../Query/GearsOfWarQuerySqliteTest.cs | 101 +--- .../Query/SimpleQuerySqliteTest.cs | 8 +- .../Query/ExpressionPrinterTest.cs | 169 +++++++ 24 files changed, 1000 insertions(+), 1146 deletions(-) create mode 100644 test/EFCore.Tests/Query/ExpressionPrinterTest.cs diff --git a/src/EFCore/Metadata/Internal/NavigationExtensions.cs b/src/EFCore/Metadata/Internal/NavigationExtensions.cs index 2be9bae6b4f..9274cf19cc8 100644 --- a/src/EFCore/Metadata/Internal/NavigationExtensions.cs +++ b/src/EFCore/Metadata/Internal/NavigationExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Runtime.CompilerServices; using System.Text; using JetBrains.Annotations; @@ -17,6 +18,20 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal /// public static class NavigationExtensions { + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + [Obsolete] + public static string ToDebugString( + [NotNull] this INavigation navigation, + bool singleLine, + bool includeIndexes, + [NotNull] string indent) + => ToDebugString(navigation, singleLine, includeIndexes, indent, detailed: true); + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -27,7 +42,8 @@ public static string ToDebugString( [NotNull] this INavigation navigation, bool singleLine = true, bool includeIndexes = false, - [NotNull] string indent = "") + [NotNull] string indent = "", + bool detailed = true) { var builder = new StringBuilder(); @@ -35,11 +51,16 @@ public static string ToDebugString( if (singleLine) { - builder.Append("Navigation: ").Append(navigation.DeclaringEntityType.DisplayName()).Append("."); + builder.Append($"Navigation: {navigation.DeclaringEntityType.DisplayName()}."); } builder.Append(navigation.Name); + if (!detailed) + { + return builder.ToString(); + } + if (navigation.GetFieldName() == null) { builder.Append(" (no field, "); @@ -80,10 +101,7 @@ public static string ToDebugString( builder.Append(" ").Append(indexes.StoreGenerationIndex); } - if (!singleLine) - { - builder.Append(navigation.AnnotationsToDebugString(indent + " ")); - } + builder.Append(navigation.AnnotationsToDebugString(indent + " ")); return builder.ToString(); } diff --git a/src/EFCore/Query/ExpressionPrinter.cs b/src/EFCore/Query/ExpressionPrinter.cs index a091fa4db0a..68d49d1c912 100644 --- a/src/EFCore/Query/ExpressionPrinter.cs +++ b/src/EFCore/Query/ExpressionPrinter.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Runtime.CompilerServices; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -428,7 +429,10 @@ protected override Expression VisitLabel(LabelExpression labelExpression) protected override Expression VisitLambda(Expression lambdaExpression) { - _stringBuilder.Append("("); + if (lambdaExpression.Parameters.Count != 1) + { + _stringBuilder.Append("("); + } foreach (var parameter in lambdaExpression.Parameters) { @@ -447,7 +451,12 @@ protected override Expression VisitLambda(Expression lambdaExpression) } } - _stringBuilder.Append(") => "); + if (lambdaExpression.Parameters.Count != 1) + { + _stringBuilder.Append(")"); + } + + _stringBuilder.Append(" => "); Visit(lambdaExpression.Body); @@ -464,7 +473,8 @@ protected override Expression VisitMember(MemberExpression memberExpression) { if (memberExpression.Expression != null) { - if (memberExpression.Expression.NodeType == ExpressionType.Convert) + if (memberExpression.Expression.NodeType == ExpressionType.Convert + || memberExpression.Expression is BinaryExpression) { _stringBuilder.Append("("); Visit(memberExpression.Expression); @@ -534,34 +544,61 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp _stringBuilder.Append("."); } - _stringBuilder.Append(methodCallExpression.Method.Name); - if (methodCallExpression.Method.IsGenericMethod) + var methodArguments = methodCallExpression.Arguments.ToList(); + + // TODO: issue #18413 + var simplifiedMethod = !GenerateUniqueParameterIds + && methodCallExpression.Arguments.Count > 0 + && methodCallExpression.Method.IsDefined(typeof(ExtensionAttribute), inherit: false); + + if (simplifiedMethod) { - _stringBuilder.Append("<"); - var first = true; - foreach (var genericArgument in methodCallExpression.Method.GetGenericArguments()) + Visit(methodArguments[0]); + + var methodDeclaringType = methodCallExpression.Method.DeclaringType; + if (methodDeclaringType == typeof(Queryable) + || methodDeclaringType == typeof(Enumerable) + || methodDeclaringType == typeof(QueryableExtensions) + || methodDeclaringType == typeof(EnumerableExtensions)) { - if (!first) + _stringBuilder.IncrementIndent(); + _stringBuilder.AppendLine(); + } + + _stringBuilder.Append($".{methodCallExpression.Method.Name}"); + methodArguments = methodArguments.Skip(1).ToList(); + } + else + { + _stringBuilder.Append(methodCallExpression.Method.Name); + if (methodCallExpression.Method.IsGenericMethod) + { + _stringBuilder.Append("<"); + var first = true; + foreach (var genericArgument in methodCallExpression.Method.GetGenericArguments()) { - _stringBuilder.Append(", "); + if (!first) + { + _stringBuilder.Append(", "); + } + + _stringBuilder.Append(genericArgument.ShortDisplayName()); + first = false; } - _stringBuilder.Append(genericArgument.ShortDisplayName()); - first = false; + _stringBuilder.Append(">"); } - - _stringBuilder.Append(">"); } _stringBuilder.Append("("); var isSimpleMethodOrProperty = _simpleMethods.Contains(methodCallExpression.Method.Name) - || methodCallExpression.Arguments.Count < 2 + || methodArguments.Count < 2 || methodCallExpression.Method.IsEFPropertyMethod(); var appendAction = isSimpleMethodOrProperty ? (Action)Append : AppendLine; - if (methodCallExpression.Arguments.Count > 0) + if (methodArguments.Count > 0) { appendAction(""); @@ -577,9 +614,9 @@ var argumentNames indent = _stringBuilder.Indent(); } - for (var i = 0; i < methodCallExpression.Arguments.Count; i++) + for (var i = 0; i < methodArguments.Count; i++) { - var argument = methodCallExpression.Arguments[i]; + var argument = methodArguments[i]; if (!isSimpleMethodOrProperty) { @@ -588,7 +625,7 @@ var argumentNames Visit(argument); - if (i < methodCallExpression.Arguments.Count - 1) + if (i < methodArguments.Count - 1) { appendAction(", "); } @@ -602,6 +639,11 @@ var argumentNames Append(")"); + if (simplifiedMethod) + { + _stringBuilder.DecrementIndent(); + } + return methodCallExpression; } @@ -712,9 +754,17 @@ protected override Expression VisitParameter(ParameterExpression parameterExpres } else { - Append("(Unhandled parameter: "); - Append(parameterExpression.Name); - Append(")"); + // TODO: issue #18413 + if (GenerateUniqueParameterIds) + { + Append("(Unhandled parameter: "); + Append(parameterExpression.Name); + Append(")"); + } + else + { + Append(parameterExpression.Name); + } } if (GenerateUniqueParameterIds) @@ -829,7 +879,9 @@ protected override Expression VisitExtension(Expression extensionExpression) { if (extensionExpression is IPrintableExpression printable) { + _stringBuilder.Append("("); printable.Print(this); + _stringBuilder.Append(")"); } else { @@ -840,7 +892,10 @@ protected override Expression VisitExtension(Expression extensionExpression) } private void VisitArguments( - IReadOnlyList arguments, Action appendAction, string lastSeparator = "", bool areConnected = false) + IReadOnlyList arguments, + Action appendAction, + string lastSeparator = "", + bool areConnected = false) { for (var i = 0; i < arguments.Count; i++) { diff --git a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs index c894ba347e6..b4cb37ea150 100644 --- a/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs +++ b/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.Expressions.cs @@ -189,8 +189,7 @@ public virtual void MarkAsOptional() public virtual void Print(ExpressionPrinter expressionPrinter) { - expressionPrinter.Append(nameof(EntityReference)); - expressionPrinter.Append(EntityType.DisplayName()); + expressionPrinter.Append($"{nameof(EntityReference)}: {EntityType.DisplayName()}"); if (IsOptional) { expressionPrinter.Append("[Optional]"); diff --git a/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs b/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs index 01f4f3ae36b..d487f58f956 100644 --- a/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs +++ b/src/EFCore/Query/MaterializeCollectionNavigationExpression.cs @@ -4,6 +4,7 @@ using System; using System.Linq.Expressions; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Microsoft.EntityFrameworkCore.Query { @@ -31,9 +32,13 @@ public virtual MaterializeCollectionNavigationExpression Update(Expression subqu public virtual void Print(ExpressionPrinter expressionPrinter) { - expressionPrinter.Append($"MaterializeCollectionNavigation({Navigation}, "); - expressionPrinter.Visit(Subquery); - expressionPrinter.Append(")"); + expressionPrinter.AppendLine("MaterializeCollectionNavigation("); + using (expressionPrinter.Indent()) + { + expressionPrinter.AppendLine($"navigation: {Navigation.ToDebugString(detailed: false)},"); + expressionPrinter.Append("subquery: "); + expressionPrinter.Visit(Subquery); + } } } } diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.cs index 5b7cab4621b..0eba1ebfd2c 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.cs @@ -283,14 +283,9 @@ public override Task Default_if_empty_top_level_arg(bool isAsync) } [ConditionalTheory(Skip = "Issue #17246")] - public override async Task Default_if_empty_top_level_arg_followed_by_projecting_constant(bool isAsync) + public override Task Default_if_empty_top_level_arg_followed_by_projecting_constant(bool isAsync) { - await base.Default_if_empty_top_level_arg_followed_by_projecting_constant(isAsync); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Customer"")"); + return base.Default_if_empty_top_level_arg_followed_by_projecting_constant(isAsync); } [ConditionalTheory(Skip = "Issue#17246")] @@ -2197,70 +2192,40 @@ FROM root c WHERE ((c[""Discriminator""] = ""Order"") AND (c[""OrderDate""] > @__p_0))"); } - [ConditionalFact(Skip = "Issue #17246")] - public override void Random_next_is_not_funcletized_1() + [ConditionalTheory(Skip = "Issue #17246")] + public override Task Random_next_is_not_funcletized_1(bool isAsync) { - base.Random_next_is_not_funcletized_1(); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Order"")"); + return base.Random_next_is_not_funcletized_1(isAsync); } - [ConditionalFact(Skip = "Issue #17246")] - public override void Random_next_is_not_funcletized_2() + [ConditionalTheory(Skip = "Issue #17246")] + public override Task Random_next_is_not_funcletized_2(bool isAsync) { - base.Random_next_is_not_funcletized_2(); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Order"")"); + return base.Random_next_is_not_funcletized_2(isAsync); } - [ConditionalFact(Skip = "Issue #17246")] - public override void Random_next_is_not_funcletized_3() + [ConditionalTheory(Skip = "Issue #17246")] + public override Task Random_next_is_not_funcletized_3(bool isAsync) { - base.Random_next_is_not_funcletized_3(); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Order"")"); + return base.Random_next_is_not_funcletized_3(isAsync); } - [ConditionalFact(Skip = "Issue #17246")] - public override void Random_next_is_not_funcletized_4() + [ConditionalTheory(Skip = "Issue #17246")] + public override Task Random_next_is_not_funcletized_4(bool isAsync) { - base.Random_next_is_not_funcletized_4(); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Order"")"); + return base.Random_next_is_not_funcletized_4(isAsync); } - [ConditionalFact(Skip = "Issue #17246")] - public override void Random_next_is_not_funcletized_5() + [ConditionalTheory(Skip = "Issue #17246")] + public override Task Random_next_is_not_funcletized_5(bool isAsync) { - base.Random_next_is_not_funcletized_5(); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Order"")"); + return base.Random_next_is_not_funcletized_5(isAsync); } - [ConditionalFact(Skip = "Issue #17246")] - public override void Random_next_is_not_funcletized_6() + [ConditionalTheory(Skip = "Issue #17246")] + public override Task Random_next_is_not_funcletized_6(bool isAsync) { - base.Random_next_is_not_funcletized_6(); - - AssertSql( - @"SELECT c -FROM root c -WHERE (c[""Discriminator""] = ""Order"")"); + return base.Random_next_is_not_funcletized_6(isAsync); } [ConditionalTheory(Skip = "Issue #17246")] @@ -4108,13 +4073,9 @@ public override Task Subquery_member_pushdown_does_not_change_original_subquery_ [ConditionalTheory(Skip = "Issue #17246")] public override Task Where_query_composition3(bool isAsync) => base.Where_query_composition3(isAsync); - public override async Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool isAsync) + public override Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => new CustomerListItem( c.CustomerID, c.City ).City)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync))).Message)); + return AssertTranslationFailed(() => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync)); } [ConditionalTheory(Skip = "Issue #17246")] diff --git a/test/EFCore.InMemory.FunctionalTests/Query/InheritanceInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/InheritanceInMemoryTest.cs index 3fd19efebd9..c1220ed941b 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/InheritanceInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/InheritanceInMemoryTest.cs @@ -19,10 +19,13 @@ public InheritanceInMemoryTest(InheritanceInMemoryFixture fixture, ITestOutputHe [ConditionalFact] public override void Can_query_all_animal_views() { + var message = Assert.Throws(() => base.Can_query_all_animal_views()).Message; + Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: Select( source: DbSet, selector: (b) => MaterializeView(b)), keySelector: (a) => a.CountryId)"), - Assert.Throws(() => base.Can_query_all_animal_views()) - .Message.Replace("\r", "").Replace("\n", "")); + CoreStrings.TranslationFailed(@"DbSet + .Select(b => MaterializeView(b)) + .OrderBy(a => a.CountryId)"), + message); } protected override bool EnforcesFkConstraints => false; diff --git a/test/EFCore.InMemory.FunctionalTests/Query/SimpleQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/SimpleQueryInMemoryTest.cs index 3619dd58866..ff04d97f10f 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/SimpleQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/SimpleQueryInMemoryTest.cs @@ -109,40 +109,40 @@ public override Task OrderBy_multiple_queries(bool isAsync) return base.OrderBy_multiple_queries(isAsync); } - [ConditionalFact(Skip = "Issue#17386")] - public override void Random_next_is_not_funcletized_1() + [ConditionalTheory(Skip = "Issue#17386")] + public override Task Random_next_is_not_funcletized_1(bool isAsync) { - base.Random_next_is_not_funcletized_1(); + return base.Random_next_is_not_funcletized_1(isAsync); } - [ConditionalFact(Skip = "Issue#17386")] - public override void Random_next_is_not_funcletized_2() + [ConditionalTheory(Skip = "Issue#17386")] + public override Task Random_next_is_not_funcletized_2(bool isAsync) { - base.Random_next_is_not_funcletized_2(); + return base.Random_next_is_not_funcletized_2(isAsync); } - [ConditionalFact(Skip = "Issue#17386")] - public override void Random_next_is_not_funcletized_3() + [ConditionalTheory(Skip = "Issue#17386")] + public override Task Random_next_is_not_funcletized_3(bool isAsync) { - base.Random_next_is_not_funcletized_3(); + return base.Random_next_is_not_funcletized_3(isAsync); } - [ConditionalFact(Skip = "Issue#17386")] - public override void Random_next_is_not_funcletized_4() + [ConditionalTheory(Skip = "Issue#17386")] + public override Task Random_next_is_not_funcletized_4(bool isAsync) { - base.Random_next_is_not_funcletized_4(); + return base.Random_next_is_not_funcletized_4(isAsync); } - [ConditionalFact(Skip = "Issue#17386")] - public override void Random_next_is_not_funcletized_5() + [ConditionalTheory(Skip = "Issue#17386")] + public override Task Random_next_is_not_funcletized_5(bool isAsync) { - base.Random_next_is_not_funcletized_5(); + return base.Random_next_is_not_funcletized_5(isAsync); } - [ConditionalFact(Skip = "Issue#17386")] - public override void Random_next_is_not_funcletized_6() + [ConditionalTheory(Skip = "Issue#17386")] + public override Task Random_next_is_not_funcletized_6(bool isAsync) { - base.Random_next_is_not_funcletized_6(); + return base.Random_next_is_not_funcletized_6(isAsync); } [ConditionalTheory(Skip = "Issue#17386")] diff --git a/test/EFCore.Relational.Specification.Tests/Query/QueryNoClientEvalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/QueryNoClientEvalTestBase.cs index 9531a643fa8..dd63acfdebc 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/QueryNoClientEvalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/QueryNoClientEvalTestBase.cs @@ -24,11 +24,7 @@ public virtual void Throws_when_where() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.Where(c => c.IsLondon).ToList()) - .Message)); + AssertTranslationFailed(() => context.Customers.Where(c => c.IsLondon).ToList()); } } @@ -37,10 +33,7 @@ public virtual void Throws_when_orderby() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.OrderBy(c => c.IsLondon).ToList()).Message)); + AssertTranslationFailed(() => context.Customers.OrderBy(c => c.IsLondon).ToList()); } } @@ -49,13 +42,11 @@ public virtual void Throws_when_orderby_multiple() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers - .OrderBy(c => c.IsLondon) - .ThenBy(c => ClientMethod(c)) - .ToList()).Message)); + AssertTranslationFailed( + () => context.Customers + .OrderBy(c => c.IsLondon) + .ThenBy(c => ClientMethod(c)) + .ToList()); } } @@ -66,16 +57,10 @@ public virtual void Throws_when_where_subquery_correlated() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Any( source: DbSet, predicate: (c0) => EntityShaperExpression: EntityType: Customer ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False .CustomerID == c0.CustomerID && c0.IsLondon)"), - RemoveNewLines( - Assert.Throws( - () => context.Customers - .Where( - c1 => context.Customers - .Any(c2 => c1.CustomerID == c2.CustomerID && c2.IsLondon)) - .ToList()).Message)); + AssertTranslationFailed( + () => context.Customers + .Where(c1 => context.Customers.Any(c2 => c1.CustomerID == c2.CustomerID && c2.IsLondon)) + .ToList()); } } @@ -84,10 +69,7 @@ public virtual void Throws_when_all() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("All( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.All(c => c.IsLondon)).Message)); + AssertTranslationFailed(() => context.Customers.All(c => c.IsLondon)); } } @@ -96,13 +78,11 @@ public virtual void Throws_when_from_sql_composed() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: FromSqlOnQueryable( source: DbSet, sql: \"select * from \"Customers\"\", parameters: (Unhandled parameter: __p_0)), predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers - .FromSqlRaw(NormalizeDelimetersInRawString("select * from [Customers]")) - .Where(c => c.IsLondon) - .ToList()).Message)); + AssertTranslationFailed( + () => context.Customers + .FromSqlRaw(NormalizeDelimetersInRawString("select * from [Customers]")) + .Where(c => c.IsLondon) + .ToList()); } } @@ -125,16 +105,13 @@ public virtual void Throws_when_subquery_main_from_clause() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => - (from c1 in context.Customers - .Where(c => c.IsLondon) - .OrderBy(c => c.CustomerID) - .Take(5) - select c1) - .ToList()).Message)); + AssertTranslationFailed( + () => (from c1 in context.Customers + .Where(c => c.IsLondon) + .OrderBy(c => c.CustomerID) + .Take(5) + select c1) + .ToList()); } } @@ -144,13 +121,14 @@ public virtual void Throws_when_select_many() using (var context = CreateContext()) { Assert.Equal( - CoreStrings.QueryFailed("(c1) => int[] { 1, 2, 3, }", "NavigationExpandingExpressionVisitor"), - RemoveNewLines(Assert.Throws( - () => - (from c1 in context.Customers - from i in new[] { 1, 2, 3 } - select c1) - .ToList()).Message)); + CoreStrings.QueryFailed( + "c1 => int[] { 1, 2, 3, }", + "NavigationExpandingExpressionVisitor"), + Assert.Throws( + () => (from c1 in context.Customers + from i in new[] { 1, 2, 3 } + select c1) + .ToList()).Message); } } @@ -159,17 +137,22 @@ public virtual void Throws_when_join() { using (var context = CreateContext()) { + var message = Assert.Throws( + () => (from e1 in context.Employees + join i in new uint[] { 1, 2, 3 } on e1.EmployeeID equals i + select e1) + .ToList()).Message; + Assert.Equal( CoreStrings.QueryFailed( - @"Join( outer: DbSet, inner: (Unhandled parameter: __p_0), outerKeySelector: (e1) => e1.EmployeeID, innerKeySelector: (i) => i, resultSelector: (e1, i) => e1)", + @"DbSet + .Join( + outer: (Unhandled parameter: __p_0), + inner: e1 => e1.EmployeeID, + outerKeySelector: i => i, + innerKeySelector: (e1, i) => e1)", "NavigationExpandingExpressionVisitor"), - RemoveNewLines( - Assert.Throws( - () => - (from e1 in context.Employees - join i in new uint[] { 1, 2, 3 } on e1.EmployeeID equals i - select e1) - .ToList()).Message)); + message); } } @@ -178,17 +161,22 @@ public virtual void Throws_when_group_join() { using (var context = CreateContext()) { + var message = Assert.Throws( + () => (from e1 in context.Employees + join i in new uint[] { 1, 2, 3 } on e1.EmployeeID equals i into g + select e1) + .ToList()).Message; + Assert.Equal( CoreStrings.QueryFailed( - "GroupJoin( outer: DbSet, inner: (Unhandled parameter: __p_0), outerKeySelector: (e1) => e1.EmployeeID, innerKeySelector: (i) => i, resultSelector: (e1, g) => e1)", + @"DbSet + .GroupJoin( + outer: (Unhandled parameter: __p_0), + inner: e1 => e1.EmployeeID, + outerKeySelector: i => i, + innerKeySelector: (e1, g) => e1)", "NavigationExpandingExpressionVisitor"), - RemoveNewLines( - Assert.Throws( - () => - (from e1 in context.Employees - join i in new uint[] { 1, 2, 3 } on e1.EmployeeID equals i into g - select e1) - .ToList()).Message)); + message); } } @@ -200,12 +188,11 @@ public virtual void Throws_when_group_by() context.Customers .GroupBy(c => c.CustomerID) .ToList(); - Assert.Equal( - CoreStrings.TranslationFailed("GroupBy([c].CustomerID, [c])"), - RemoveNewLines(Assert.Throws( - () => context.Customers - .GroupBy(c => c.CustomerID) - .ToList()).Message)); + + AssertTranslationFailed( + () => context.Customers + .GroupBy(c => c.CustomerID) + .ToList()); } } @@ -214,10 +201,7 @@ public virtual void Throws_when_first() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.First(c => c.IsLondon)).Message)); + AssertTranslationFailed(() => context.Customers.First(c => c.IsLondon)); } } @@ -226,10 +210,7 @@ public virtual void Throws_when_single() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.Single(c => c.IsLondon)).Message)); + AssertTranslationFailed(() => context.Customers.Single(c => c.IsLondon)); } } @@ -238,10 +219,7 @@ public virtual void Throws_when_first_or_default() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.FirstOrDefault(c => c.IsLondon)).Message)); + AssertTranslationFailed(() => context.Customers.FirstOrDefault(c => c.IsLondon)); } } @@ -250,21 +228,19 @@ public virtual void Throws_when_single_or_default() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines(Assert.Throws( - () => context.Customers.SingleOrDefault(c => c.IsLondon)).Message)); + AssertTranslationFailed(() => context.Customers.SingleOrDefault(c => c.IsLondon)); } } - private string RemoveNewLines(string message) - => message.Replace("\n", "").Replace("\r", ""); - private string NormalizeDelimetersInRawString(string sql) => Fixture.TestStore.NormalizeDelimetersInRawString(sql); - private FormattableString NormalizeDelimetersInInterpolatedString(FormattableString sql) - => Fixture.TestStore.NormalizeDelimetersInInterpolatedString(sql); + private void AssertTranslationFailed(Action testCode) + { + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + Assert.Throws(testCode).Message); + } protected NorthwindContext CreateContext() => Fixture.CreateContext(); } diff --git a/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs index 8e6f5b4a86c..8caf6c6b0cc 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/UdfDbFunctionTestBase.cs @@ -419,12 +419,10 @@ public virtual void Scalar_Nested_Function_Unwind_Client_Eval_Where_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 2 == AddOneStatic(c.Id))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == UDFSqlContext.AddOneStatic(c.Id) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == UDFSqlContext.AddOneStatic(c.Id) + select c.Id).Single()); } [ConditionalFact] @@ -432,12 +430,10 @@ public virtual void Scalar_Nested_Function_Unwind_Client_Eval_OrderBy_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => AddOneStatic(c.Id))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - orderby UDFSqlContext.AddOneStatic(c.Id) - select c.Id).ToList()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + orderby UDFSqlContext.AddOneStatic(c.Id) + select c.Id).ToList()); } [ConditionalFact] @@ -458,13 +454,10 @@ public virtual void Scalar_Nested_Function_Client_BCL_UDF_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == AddOneStatic(Abs(CustomerOrderCountWithClientStatic(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == UDFSqlContext.AddOneStatic(Math.Abs(UDFSqlContext.CustomerOrderCountWithClientStatic(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == UDFSqlContext.AddOneStatic(Math.Abs(UDFSqlContext.CustomerOrderCountWithClientStatic(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -472,13 +465,10 @@ public virtual void Scalar_Nested_Function_Client_UDF_BCL_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == AddOneStatic(CustomerOrderCountWithClientStatic(Abs(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == UDFSqlContext.AddOneStatic(UDFSqlContext.CustomerOrderCountWithClientStatic(Math.Abs(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == UDFSqlContext.AddOneStatic(UDFSqlContext.CustomerOrderCountWithClientStatic(Math.Abs(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -486,13 +476,10 @@ public virtual void Scalar_Nested_Function_BCL_Client_UDF_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == Abs(AddOneStatic(CustomerOrderCountWithClientStatic(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == Math.Abs(UDFSqlContext.AddOneStatic(UDFSqlContext.CustomerOrderCountWithClientStatic(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == Math.Abs(UDFSqlContext.AddOneStatic(UDFSqlContext.CustomerOrderCountWithClientStatic(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -500,13 +487,10 @@ public virtual void Scalar_Nested_Function_BCL_UDF_Client_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 1 == Abs(CustomerOrderCountWithClientStatic(AddOneStatic(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 1 == Math.Abs(UDFSqlContext.CustomerOrderCountWithClientStatic(UDFSqlContext.AddOneStatic(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 1 == Math.Abs(UDFSqlContext.CustomerOrderCountWithClientStatic(UDFSqlContext.AddOneStatic(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -514,13 +498,10 @@ public virtual void Scalar_Nested_Function_UDF_BCL_Client_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 1 == CustomerOrderCountWithClientStatic(Abs(AddOneStatic(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 1 == UDFSqlContext.CustomerOrderCountWithClientStatic(Math.Abs(UDFSqlContext.AddOneStatic(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 1 == UDFSqlContext.CustomerOrderCountWithClientStatic(Math.Abs(UDFSqlContext.AddOneStatic(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -528,13 +509,10 @@ public virtual void Scalar_Nested_Function_UDF_Client_BCL_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 1 == CustomerOrderCountWithClientStatic(AddOneStatic(Abs(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 1 == UDFSqlContext.CustomerOrderCountWithClientStatic(UDFSqlContext.AddOneStatic(Math.Abs(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 1 == UDFSqlContext.CustomerOrderCountWithClientStatic(UDFSqlContext.AddOneStatic(Math.Abs(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -542,12 +520,10 @@ public virtual void Scalar_Nested_Function_Client_BCL_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 3 == AddOneStatic(Abs(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 3 == UDFSqlContext.AddOneStatic(Math.Abs(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 3 == UDFSqlContext.AddOneStatic(Math.Abs(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -555,12 +531,10 @@ public virtual void Scalar_Nested_Function_Client_UDF_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 2 == AddOneStatic(CustomerOrderCountWithClientStatic(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == UDFSqlContext.AddOneStatic(UDFSqlContext.CustomerOrderCountWithClientStatic(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == UDFSqlContext.AddOneStatic(UDFSqlContext.CustomerOrderCountWithClientStatic(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -568,12 +542,10 @@ public virtual void Scalar_Nested_Function_BCL_Client_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 3 == Abs(AddOneStatic(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 3 == Math.Abs(UDFSqlContext.AddOneStatic(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 3 == Math.Abs(UDFSqlContext.AddOneStatic(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -593,12 +565,10 @@ public virtual void Scalar_Nested_Function_UDF_Client_Static() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 2 == CustomerOrderCountWithClientStatic(AddOneStatic(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == UDFSqlContext.CustomerOrderCountWithClientStatic(UDFSqlContext.AddOneStatic(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == UDFSqlContext.CustomerOrderCountWithClientStatic(UDFSqlContext.AddOneStatic(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -876,12 +846,10 @@ public virtual void Scalar_Nested_Function_Unwind_Client_Eval_Where_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 2 == (Unhandled parameter: __context_0).AddOneInstance(c.Id))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == context.AddOneInstance(c.Id) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == context.AddOneInstance(c.Id) + select c.Id).Single()); } [ConditionalFact] @@ -889,12 +857,10 @@ public virtual void Scalar_Nested_Function_Unwind_Client_Eval_OrderBy_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => (Unhandled parameter: __context_0).AddOneInstance(c.Id))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - orderby context.AddOneInstance(c.Id) - select c.Id).ToList()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + orderby context.AddOneInstance(c.Id) + select c.Id).ToList()); } [ConditionalFact] @@ -915,13 +881,10 @@ public virtual void Scalar_Nested_Function_Client_BCL_UDF_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == (Unhandled parameter: __context_0).AddOneInstance(Abs((Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == context.AddOneInstance(Math.Abs(context.CustomerOrderCountWithClientInstance(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == context.AddOneInstance(Math.Abs(context.CustomerOrderCountWithClientInstance(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -929,13 +892,10 @@ public virtual void Scalar_Nested_Function_Client_UDF_BCL_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == (Unhandled parameter: __context_0).AddOneInstance((Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance(Abs(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == context.AddOneInstance(context.CustomerOrderCountWithClientInstance(Math.Abs(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == context.AddOneInstance(context.CustomerOrderCountWithClientInstance(Math.Abs(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -943,12 +903,10 @@ public virtual void Scalar_Nested_Function_BCL_Client_UDF_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 2 == Abs((Unhandled parameter: __context_0).AddOneInstance((Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == Math.Abs(context.AddOneInstance(context.CustomerOrderCountWithClientInstance(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == Math.Abs(context.AddOneInstance(context.CustomerOrderCountWithClientInstance(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -956,13 +914,10 @@ public virtual void Scalar_Nested_Function_BCL_UDF_Client_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 1 == Abs((Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance((Unhandled parameter: __context_0).AddOneInstance(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 1 == Math.Abs(context.CustomerOrderCountWithClientInstance(context.AddOneInstance(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 1 == Math.Abs(context.CustomerOrderCountWithClientInstance(context.AddOneInstance(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -970,13 +925,10 @@ public virtual void Scalar_Nested_Function_UDF_BCL_Client_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 1 == (Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance(Abs((Unhandled parameter: __context_0).AddOneInstance(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 1 == context.CustomerOrderCountWithClientInstance(Math.Abs(context.AddOneInstance(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 1 == context.CustomerOrderCountWithClientInstance(Math.Abs(context.AddOneInstance(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -984,13 +936,10 @@ public virtual void Scalar_Nested_Function_UDF_Client_BCL_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 1 == (Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance((Unhandled parameter: __context_0).AddOneInstance(Abs(c.Id))))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 1 == context.CustomerOrderCountWithClientInstance(context.AddOneInstance(Math.Abs(c.Id))) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 1 == context.CustomerOrderCountWithClientInstance(context.AddOneInstance(Math.Abs(c.Id))) + select c.Id).Single()); } [ConditionalFact] @@ -998,13 +947,10 @@ public virtual void Scalar_Nested_Function_Client_BCL_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 3 == (Unhandled parameter: __context_0).AddOneInstance(Abs(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 3 == context.AddOneInstance(Math.Abs(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 3 == context.AddOneInstance(Math.Abs(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -1012,13 +958,10 @@ public virtual void Scalar_Nested_Function_Client_UDF_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == (Unhandled parameter: __context_0).AddOneInstance((Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == context.AddOneInstance(context.CustomerOrderCountWithClientInstance(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == context.AddOneInstance(context.CustomerOrderCountWithClientInstance(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -1026,12 +969,10 @@ public virtual void Scalar_Nested_Function_BCL_Client_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => 3 == Abs((Unhandled parameter: __context_0).AddOneInstance(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 3 == Math.Abs(context.AddOneInstance(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 3 == Math.Abs(context.AddOneInstance(c.Id)) + select c.Id).Single()); } public static Exception AssertThrows(Func testCode) @@ -1058,13 +999,10 @@ public virtual void Scalar_Nested_Function_UDF_Client_Instance() { using var context = CreateContext(); - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => 2 == (Unhandled parameter: __context_0).CustomerOrderCountWithClientInstance((Unhandled parameter: __context_0).AddOneInstance(c.Id)))"), - RemoveNewLines(Assert.Throws( - () => (from c in context.Customers - where 2 == context.CustomerOrderCountWithClientInstance(context.AddOneInstance(c.Id)) - select c.Id).Single()).Message)); + AssertTranslationFailed( + () => (from c in context.Customers + where 2 == context.CustomerOrderCountWithClientInstance(context.AddOneInstance(c.Id)) + select c.Id).Single()); } [ConditionalFact] @@ -1083,7 +1021,11 @@ public virtual void Scalar_Nested_Function_UDF_BCL_Instance() #endregion - private string RemoveNewLines(string message) - => message.Replace("\n", "").Replace("\r", ""); + private void AssertTranslationFailed(Action testCode) + { + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + Assert.Throws(testCode).Message); + } } } diff --git a/test/EFCore.Specification.Tests/Query/FiltersTestBase.cs b/test/EFCore.Specification.Tests/Query/FiltersTestBase.cs index f143e58991b..9661b10f21a 100644 --- a/test/EFCore.Specification.Tests/Query/FiltersTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/FiltersTestBase.cs @@ -51,7 +51,7 @@ public virtual void Find() public virtual void Client_eval() { Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (p) => ClientMethod(p))"), + CoreStrings.TranslationFailed("DbSet .Where(p => ClientMethod(p))"), RemoveNewLines(Assert.Throws( () => _context.Products.ToList()).Message)); } @@ -135,7 +135,7 @@ public virtual void Project_reference_that_itself_has_query_filter_with_another_ public virtual void Included_one_to_many_query_with_client_eval() { Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (p) => ClientMethod(p))"), + CoreStrings.TranslationFailed("DbSet .Where(p => ClientMethod(p))"), RemoveNewLines(Assert.Throws( () => _context.Products.Include(p => p.OrderDetails).ToList()).Message)); } diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index 5849a2ef08d..c0dce829b39 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -1308,9 +1308,9 @@ orderby g.Nickname [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_conditional_with_anonymous_type(bool isAsync) + public virtual Task Where_conditional_with_anonymous_type(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => from g in ss.Set() @@ -1322,11 +1322,7 @@ orderby g.Nickname } : null) == null select g.Nickname, - assertOrder: true))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: OrderBy( source: DbSet, keySelector: (g) => g.Nickname), predicate: (g) => g.LeaderNickname != null ? new { HasSoulPatch = g.HasSoulPatch } : null == null)"), - RemoveNewLines(message)); + assertOrder: true)); } [ConditionalTheory] @@ -1349,9 +1345,9 @@ orderby g.Nickname [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_coalesce_with_anonymous_types(bool isAsync) + public virtual Task Where_coalesce_with_anonymous_types(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => from g in ss.Set() @@ -1362,11 +1358,7 @@ public virtual async Task Where_coalesce_with_anonymous_types(bool isAsync) { Name = g.FullName }) != null - select g.Nickname))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (g) => new { Name = g.LeaderNickname } ?? new { Name = g.FullName } != null)"), - RemoveNewLines(message)); + select g.Nickname)); } [ConditionalTheory(Skip = "issue #8421")] @@ -1723,7 +1715,7 @@ public virtual async Task Select_navigation_with_concat_and_count(bool isAsync) ss => ss.Set().Where(g => !g.HasSoulPatch).Select(g => g.Weapons.Concat(g.Weapons).Count())))).Message; Assert.Equal( - CoreStrings.QueryFailed("Concat( source1: AsQueryable(MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: NavigationExpansionExpression Source: Where( source: DbSet, predicate: (w) => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w, \"OwnerFullName\")) PendingSelector: (w) => NavigationTreeExpression Value: EntityReferenceWeapon Expression: w , predicate: (i) => Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\")))), source2: MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: NavigationExpansionExpression Source: Where( source: DbSet, predicate: (w0) => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w0, \"OwnerFullName\")) PendingSelector: (w0) => NavigationTreeExpression Value: EntityReferenceWeapon Expression: w0 , predicate: (i) => Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\"))))", "NavigationExpandingExpressionVisitor"), + CoreStrings.QueryFailed("MaterializeCollectionNavigation( navigation: Navigation: Gear.Weapons, subquery: NavigationExpansionExpression Source: DbSet .Where(w => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w, \"OwnerFullName\")) PendingSelector: w => NavigationTreeExpression Value: EntityReference: Weapon Expression: w .Where(i => Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\")) .AsQueryable() .Concat(MaterializeCollectionNavigation( navigation: Navigation: Gear.Weapons, subquery: NavigationExpansionExpression Source: DbSet .Where(w0 => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w0, \"OwnerFullName\")) PendingSelector: w0 => NavigationTreeExpression Value: EntityReference: Weapon Expression: w0 .Where(i => Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\")))", "NavigationExpandingExpressionVisitor"), RemoveNewLines(message)); } @@ -1748,7 +1740,7 @@ public virtual async Task Concat_with_collection_navigations(bool isAsync) ss => ss.Set().Where(g => g.HasSoulPatch).Select(g => g.Weapons.Union(g.Weapons).Count())))).Message; Assert.Equal( - CoreStrings.QueryFailed("Union( source1: AsQueryable(MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: NavigationExpansionExpression Source: Where( source: DbSet, predicate: (w) => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w, \"OwnerFullName\")) PendingSelector: (w) => NavigationTreeExpression Value: EntityReferenceWeapon Expression: w , predicate: (i) => Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\")))), source2: MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: NavigationExpansionExpression Source: Where( source: DbSet, predicate: (w0) => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w0, \"OwnerFullName\")) PendingSelector: (w0) => NavigationTreeExpression Value: EntityReferenceWeapon Expression: w0 , predicate: (i) => Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReferenceGear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\"))))", "NavigationExpandingExpressionVisitor"), + CoreStrings.QueryFailed("MaterializeCollectionNavigation( navigation: Navigation: Gear.Weapons, subquery: NavigationExpansionExpression Source: DbSet .Where(w => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w, \"OwnerFullName\")) PendingSelector: w => NavigationTreeExpression Value: EntityReference: Weapon Expression: w .Where(i => Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\")) .AsQueryable() .Union(MaterializeCollectionNavigation( navigation: Navigation: Gear.Weapons, subquery: NavigationExpansionExpression Source: DbSet .Where(w0 => Property((Unhandled parameter: g), \"FullName\") != null && Property((Unhandled parameter: g), \"FullName\") == Property(w0, \"OwnerFullName\")) PendingSelector: w0 => NavigationTreeExpression Value: EntityReference: Weapon Expression: w0 .Where(i => Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") != null && Property(NavigationTreeExpression Value: EntityReference: Gear Expression: (Unhandled parameter: g), \"FullName\") == Property(i, \"OwnerFullName\")))", "NavigationExpandingExpressionVisitor"), RemoveNewLines(message)); } @@ -1773,18 +1765,14 @@ public virtual Task Select_subquery_distinct_firstordefault(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Select_Where_Navigation_Client(bool isAsync) + public virtual Task Select_Where_Navigation_Client(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => from t in ss.Set() where t.Gear != null && t.Gear.IsMarcus - select t))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where>( source: LeftJoin>( outer: DbSet, inner: DbSet, outerKeySelector: (c) => new AnonymousObject(new object[] { (object)Property(c, \"GearNickName\"), (object)Property>(c, \"GearSquadId\") }), innerKeySelector: (g) => new AnonymousObject(new object[] { (object)Property(g, \"Nickname\"), (object)Property>(g, \"SquadId\") }), resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), predicate: (c) => Property(c.Inner, \"Nickname\") != null && c.Inner.IsMarcus)"), - RemoveNewLines(message)); + select t)); } [ConditionalTheory] @@ -3057,18 +3045,14 @@ public virtual Task Non_flattened_GroupJoin_with_result_operator_evaluates_on_th [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Client_side_equality_with_parameter_works_with_optional_navigations(bool isAsync) + public virtual Task Client_side_equality_with_parameter_works_with_optional_navigations(bool isAsync) { var prm = "Marcus' Tag"; - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, - ss => ss.Set().Where(g => ClientEquals(g.Tag.Note, prm))))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where>( source: LeftJoin>( outer: DbSet, inner: DbSet, outerKeySelector: (g) => new AnonymousObject(new object[] { (object)Property(g, \"Nickname\"), (object)Property>(g, \"SquadId\") }), innerKeySelector: (c) => new AnonymousObject(new object[] { (object)Property(c, \"GearNickName\"), (object)Property>(c, \"GearSquadId\") }), resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), predicate: (g) => ClientEquals( first: g.Inner.Note, second: (Unhandled parameter: __prm_0)))"), - RemoveNewLines(message)); + ss => ss.Set().Where(g => ClientEquals(g.Tag.Note, prm)))); } private static bool ClientEquals(string first, string second) @@ -3362,25 +3346,21 @@ public virtual Task Select_length_of_string_property(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Client_method_on_collection_navigation_in_predicate(bool isAsync) + public virtual Task Client_method_on_collection_navigation_in_predicate(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => from g in ss.Set() where g.HasSoulPatch && FavoriteWeapon(g.Weapons).Name == "Marcus' Lancer" - select g.Nickname))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (g) => g.HasSoulPatch && FavoriteWeapon(MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: DbSet, predicate: (w) => Property(g, \"FullName\") != null && Property(g, \"FullName\") == Property(w, \"OwnerFullName\")))).Name == \"Marcus' Lancer\")"), - RemoveNewLines(message)); + select g.Nickname)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Client_method_on_collection_navigation_in_predicate_accessed_by_ef_property(bool isAsync) + public virtual Task Client_method_on_collection_navigation_in_predicate_accessed_by_ef_property(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => from g in ss.Set() @@ -3388,29 +3368,21 @@ public virtual async Task Client_method_on_collection_navigation_in_predicate_ac select g.Nickname, ss => from g in ss.Set() where !g.HasSoulPatch && FavoriteWeapon(g.Weapons).Name == "Cole's Gnasher" - select g.Nickname))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (g) => !(g.HasSoulPatch) && FavoriteWeapon(MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: DbSet, predicate: (w) => Property(g, \"FullName\") != null && Property(g, \"FullName\") == Property(w, \"OwnerFullName\")))).Name == \"Cole's Gnasher\")"), - RemoveNewLines(message)); + select g.Nickname)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Client_method_on_collection_navigation_in_order_by(bool isAsync) + public virtual Task Client_method_on_collection_navigation_in_order_by(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => from g in ss.Set() where !g.HasSoulPatch orderby FavoriteWeapon(g.Weapons).Name descending select g.Nickname, - assertOrder: true))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("OrderByDescending( source: Where( source: DbSet, predicate: (g) => !(g.HasSoulPatch)), keySelector: (g) => FavoriteWeapon(MaterializeCollectionNavigation(Navigation: Gear.Weapons (k__BackingField, ICollection) Collection ToDependent Weapon Inverse: Owner, Where( source: DbSet, predicate: (w) => Property(g, \"FullName\") != null && Property(g, \"FullName\") == Property(w, \"OwnerFullName\")))).Name)"), - RemoveNewLines(message)); + assertOrder: true)); } [ConditionalTheory] @@ -3430,7 +3402,7 @@ from v in Veterans(g.Reports) elementSorter: e => e.g + e.v))).Message; Assert.Equal( - CoreStrings.QueryFailed("(g) => Veterans(g.Reports)", "NavigationExpandingExpressionVisitor"), + CoreStrings.QueryFailed("g => Veterans(g.Reports)", "NavigationExpandingExpressionVisitor"), RemoveNewLines(message)); } @@ -6273,9 +6245,9 @@ public virtual void Include_groupby_constant_null_of_non_mapped_type() [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Correlated_collection_order_by_constant_null_of_non_mapped_type(bool isAsync) + public virtual Task Correlated_collection_order_by_constant_null_of_non_mapped_type(bool isAsync) { - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, ss => ss.Set().OrderByDescending(s => (MyDTO)null).Select( @@ -6289,11 +6261,7 @@ public virtual async Task Correlated_collection_order_by_constant_null_of_non_ma { Assert.Equal(e.Nickname, a.Nickname); AssertCollection(e.Weapons, a.Weapons); - }))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("OrderByDescending( source: DbSet, keySelector: (g) => null)"), - RemoveNewLines(message)); + })); } [ConditionalFact(Skip = "Issue #17068")] @@ -7014,18 +6982,14 @@ public virtual Task GetValueOrDefault_in_filter_non_nullable_column(bool isAsync [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task GetValueOrDefault_on_DateTimeOffset(bool isAsync) + public virtual Task GetValueOrDefault_on_DateTimeOffset(bool isAsync) { var defaultValue = default(DateTimeOffset); - var message = (await Assert.ThrowsAsync( + return AssertTranslationFailed( () => AssertQuery( isAsync, - ss => ss.Set().Where(m => ((DateTimeOffset?)m.Timeline).GetValueOrDefault() == defaultValue)))).Message; - - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => (Nullable)m.Timeline.GetValueOrDefault() == (Unhandled parameter: __defaultValue_0))"), - RemoveNewLines(message)); + ss => ss.Set().Where(m => ((DateTimeOffset?)m.Timeline).GetValueOrDefault() == defaultValue))); } [ConditionalTheory] @@ -7932,6 +7896,13 @@ public virtual Task Group_by_with_aggregate_max_on_entity_type(bool isAsync) }))); } + protected async Task AssertTranslationFailed(Func testCode) + { + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + (await Assert.ThrowsAsync(testCode)).Message); + } + protected GearsOfWarContext CreateContext() => Fixture.CreateContext(); protected virtual void ClearLog() diff --git a/test/EFCore.Specification.Tests/Query/IncludeAsyncTestBase.cs b/test/EFCore.Specification.Tests/Query/IncludeAsyncTestBase.cs index 8d3434201da..2d59a0e3a2d 100644 --- a/test/EFCore.Specification.Tests/Query/IncludeAsyncTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/IncludeAsyncTestBase.cs @@ -682,13 +682,13 @@ public virtual async Task Include_collection_with_client_filter() { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), (await Assert.ThrowsAsync( () => context.Set() .Include(c => c.Orders) .Where(c => c.IsLondon) - .ToListAsync())).Message.Replace("\r", "").Replace("\n","")); + .ToListAsync())).Message); } } diff --git a/test/EFCore.Specification.Tests/Query/IncludeTestBase.cs b/test/EFCore.Specification.Tests/Query/IncludeTestBase.cs index 1054e9ef5ac..23de2c4b40b 100644 --- a/test/EFCore.Specification.Tests/Query/IncludeTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/IncludeTestBase.cs @@ -361,14 +361,12 @@ public virtual void Include_collection_with_last_no_orderby(bool useString) { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Last(Select( source: DbSet, selector: (c) => IncludeExpression( c, MaterializeCollectionNavigation(Navigation: Customer.Orders (k__BackingField, List) Collection ToDependent Order Inverse: Customer PropertyAccessMode.Field, Where( source: DbSet, predicate: (o) => Property(c, \"CustomerID\") != null && Property(c, \"CustomerID\") == Property(o, \"CustomerID\"))), Orders)))"), - RemoveNewLines( - Assert.Throws( - () => useString - ? context.Set().Include("Orders").Last() - : context.Set().Include(c => c.Orders).Last()).Message)); + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + Assert.Throws( + () => useString + ? context.Set().Include("Orders").Last() + : context.Set().Include(c => c.Orders).Last()).Message); } } @@ -1910,8 +1908,8 @@ public virtual void Include_collection_with_client_filter(bool useString) { using (var context = CreateContext()) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), Assert.Throws( () => useString ? context.Set() @@ -4256,8 +4254,6 @@ private static void CheckIsLoaded( } } - private string RemoveNewLines(string message) => message.Replace("\n", "").Replace("\r", ""); - protected virtual void ClearLog() { } diff --git a/test/EFCore.Specification.Tests/Query/QueryNavigationsTestBase.cs b/test/EFCore.Specification.Tests/Query/QueryNavigationsTestBase.cs index 86e2685e4e4..bf2c842bafa 100644 --- a/test/EFCore.Specification.Tests/Query/QueryNavigationsTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/QueryNavigationsTestBase.cs @@ -30,20 +30,16 @@ protected virtual void ClearLog() [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Join_with_nav_projected_in_subquery_when_client_eval(bool isAsync) - { - Assert.Equal( - CoreStrings.TranslationFailed( - "Join, string, TransparentIdentifier>>( outer: DbSet, inner: LeftJoin>( outer: DbSet, inner: DbSet, outerKeySelector: (o) => Property(o, \"CustomerID\"), innerKeySelector: (c0) => Property(c0, \"CustomerID\"), resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), outerKeySelector: (c) => c.CustomerID, innerKeySelector: (o) => ClientProjection( t: o.Outer, _: o.Inner).CustomerID, resultSelector: (c, o) => new TransparentIdentifier>( Outer = c, Inner = o ))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c in ss.Set() - join o in ss.Set().Select(o => ClientProjection(o, o.Customer)) on c.CustomerID equals o.CustomerID - join od in ss.Set().Select(od => ClientProjection(od, od.Product)) on o.OrderID equals od.OrderID - select c, - entryCount: 89))).Message)); + public virtual Task Join_with_nav_projected_in_subquery_when_client_eval(bool isAsync) + { + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + join o in ss.Set().Select(o => ClientProjection(o, o.Customer)) on c.CustomerID equals o.CustomerID + join od in ss.Set().Select(od => ClientProjection(od, od.Product)) on o.OrderID equals od.OrderID + select c, + entryCount: 89)); } [ConditionalTheory(Skip = "Issue #17068")] @@ -63,19 +59,16 @@ from od in grouping2 [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Join_with_nav_in_predicate_in_subquery_when_client_eval(bool isAsync) + public virtual Task Join_with_nav_in_predicate_in_subquery_when_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where>( source: LeftJoin>( outer: DbSet, inner: DbSet, outerKeySelector: (o) => Property(o, \"CustomerID\"), innerKeySelector: (c0) => Property(c0, \"CustomerID\"), resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), predicate: (o) => ClientPredicate( t: o.Outer, _: o.Inner))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c in ss.Set() - join o in ss.Set().Where(o => ClientPredicate(o, o.Customer)) on c.CustomerID equals o.CustomerID - join od in ss.Set().Where(od => ClientPredicate(od, od.Product)) on o.OrderID equals od.OrderID - select c, - entryCount: 89))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + join o in ss.Set().Where(o => ClientPredicate(o, o.Customer)) on c.CustomerID equals o.CustomerID + join od in ss.Set().Where(od => ClientPredicate(od, od.Product)) on o.OrderID equals od.OrderID + select c, + entryCount: 89)); } [ConditionalTheory(Skip = "Issue #17068")] @@ -95,23 +88,18 @@ from od in grouping2 [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Join_with_nav_in_orderby_in_subquery_when_client_eval(bool isAsync) + public virtual Task Join_with_nav_in_orderby_in_subquery_when_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy, int>( source: LeftJoin>( outer: DbSet, inner: DbSet, outerKeySelector: (o) => Property(o, \"CustomerID\"), innerKeySelector: (c0) => Property(c0, \"CustomerID\"), resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), keySelector: (o) => ClientOrderBy( t: o.Outer, _: o.Inner))"), - RemoveNewLines((await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c in ss.Set() - join o in ss.Set().OrderBy(o => ClientOrderBy(o, o.Customer)) on c.CustomerID equals o.CustomerID - join od in ss.Set().OrderBy(od => ClientOrderBy(od, od.Product)) on o.OrderID equals od.OrderID - select c, - entryCount: 89))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + join o in ss.Set().OrderBy(o => ClientOrderBy(o, o.Customer)) on c.CustomerID equals o.CustomerID + join od in ss.Set().OrderBy(od => ClientOrderBy(od, od.Product)) on o.OrderID equals od.OrderID + select c, + entryCount: 89)); } - private string RemoveNewLines(string message) - => message.Replace("\n", "").Replace("\r", ""); - [ConditionalTheory(Skip = "Issue #17068")] [MemberData(nameof(IsAsyncData))] public virtual Task GroupJoin_with_nav_in_orderby_in_subquery_when_client_eval(bool isAsync) @@ -183,8 +171,8 @@ from o2 in ss.Set().Where(o => o.OrderID < 10400) elementSorter: e => e.o1.OrderID + " " + e.o2.OrderID, elementAsserter: (e, a) => { - AssertEqual(e.o1, a.o1); - AssertEqual(e.o2, a.o2); + AssertEqual(e.o1, a.o1); + AssertEqual(e.o2, a.o2); }, entryCount: 107); } @@ -204,19 +192,15 @@ from o2 in ss.Set().Where(o => o.OrderID < 10400) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Select_Where_Navigation_Client(bool isAsync) + public virtual Task Select_Where_Navigation_Client(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where>( source: LeftJoin>( outer: DbSet, inner: DbSet, outerKeySelector: (o) => Property(o, \"CustomerID\"), innerKeySelector: (c) => Property(c, \"CustomerID\"), resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), predicate: (o) => o.Inner.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss =>from o in ss.Set() - where o.Customer.IsLondon - select o, - entryCount: 46))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from o in ss.Set() + where o.Customer.IsLondon + select o, + entryCount: 46)); } [ConditionalTheory] @@ -655,26 +639,24 @@ public virtual Task Collection_select_nav_prop_all(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Collection_select_nav_prop_all_client(bool isAsync) + public virtual Task Collection_select_nav_prop_all_client(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("All( source: Where( source: DbSet, predicate: (o0) => Property(EntityShaperExpression: EntityType: Customer ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , \"CustomerID\") != null && Property(EntityShaperExpression: EntityType: Customer ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , \"CustomerID\") == Property(o0, \"CustomerID\")), predicate: (o0) => o0.ShipCity == \"London\")"), - RemoveNewLines((await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c in ss.Set() - orderby c.CustomerID - select new - { - All = c.Orders.All(o => o.ShipCity == "London") - }, - ss => from c in ss.Set() - orderby c.CustomerID - select new - { - All = (c.Orders ?? new List()).All(o => false) - }, - assertOrder: true))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + orderby c.CustomerID + select new + { + All = c.Orders.All(o => o.ShipCity == "London") + }, + ss => from c in ss.Set() + orderby c.CustomerID + select new + { + All = (c.Orders ?? new List()).All(o => false) + }, + assertOrder: true)); } [ConditionalTheory] @@ -692,21 +674,17 @@ where c.Orders.All(o => o.CustomerID == "ALFKI") entryCount: 3); } - [ConditionalFact] - public virtual void Collection_where_nav_prop_all_client() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Collection_where_nav_prop_all_client(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed( - "All( source: Where( source: DbSet, predicate: (o) => Property(EntityShaperExpression: EntityType: Customer ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , \"CustomerID\") != null && Property(EntityShaperExpression: EntityType: Customer ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , \"CustomerID\") == Property(o, \"CustomerID\")), predicate: (o) => o.ShipCity == \"London\")"), - RemoveNewLines( - Assert.Throws( - () => (from c in context.Set() - orderby c.CustomerID - where c.Orders.All(o => o.ShipCity == "London") - select c).ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + orderby c.CustomerID + where c.Orders.All(o => o.ShipCity == "London") + select c)); } [ConditionalTheory] @@ -1027,21 +1005,17 @@ where p.OrderDetails.Contains(ss.Set().OrderByDescending(o => o.Ord [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_subquery_on_navigation_client_eval(bool isAsync) + public virtual Task Where_subquery_on_navigation_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "OrderByDescending( source: DbSet, keySelector: (o) => ClientMethod(o.OrderID))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c in ss.Set() - orderby c.CustomerID - where c.Orders.Select(o => o.OrderID).Contains( - ss.Set().OrderByDescending(o => ClientMethod(o.OrderID)).Select(o => o.OrderID).FirstOrDefault()) - select c, - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + orderby c.CustomerID + where c.Orders.Select(o => o.OrderID).Contains( + ss.Set().OrderByDescending(o => ClientMethod(o.OrderID)).Select(o => o.OrderID).FirstOrDefault()) + select c, + entryCount: 1)); } // ReSharper disable once MemberCanBeMadeStatic.Local @@ -1378,5 +1352,12 @@ private class OrderDTO { public Customer Customer { get; set; } } + + private async Task AssertTranslationFailed(Func testCode) + { + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + (await Assert.ThrowsAsync(testCode)).Message); + } } } diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.ResultOperators.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.ResultOperators.cs index 95b1083b10b..0f3f7cdbf2e 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.ResultOperators.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.ResultOperators.cs @@ -629,7 +629,7 @@ public virtual Task Count_with_order_by(bool isAsync) [MemberData(nameof(IsAsyncData))] public virtual Task Where_OrderBy_Count(bool isAsync) { - return AssertCount( + return AssertCount( isAsync, ss => ss.Set().Where(o => o.CustomerID == "ALFKI").OrderBy(o => o.OrderID)); } @@ -665,104 +665,76 @@ public virtual Task OrderBy_Where_Count_with_predicate(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_OrderBy_Count_client_eval(bool isAsync) + public virtual Task Where_OrderBy_Count_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().Where(o => ClientEvalPredicate(o)).OrderBy(o => ClientEvalSelectorStateless())))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().Where(o => ClientEvalPredicate(o)).OrderBy(o => ClientEvalSelectorStateless()))); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_Where_Count_client_eval(bool isAsync) + public virtual Task OrderBy_Where_Count_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: OrderBy( source: DbSet, keySelector: (o) => 42), predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().OrderBy(o => ClientEvalSelectorStateless()).Where(o => ClientEvalPredicate(o))))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().OrderBy(o => ClientEvalSelectorStateless()).Where(o => ClientEvalPredicate(o)))); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_Where_Count_client_eval_mixed(bool isAsync) + public virtual Task OrderBy_Where_Count_client_eval_mixed(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: OrderBy( source: DbSet, keySelector: (o) => o.OrderID), predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().OrderBy(o => o.OrderID).Where(o => ClientEvalPredicate(o))))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().OrderBy(o => o.OrderID).Where(o => ClientEvalPredicate(o)))); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_Count_with_predicate_client_eval(bool isAsync) + public virtual Task OrderBy_Count_with_predicate_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Count( source: OrderBy( source: DbSet, keySelector: (o) => 42), predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().OrderBy(o => ClientEvalSelectorStateless()), - predicate: o => ClientEvalPredicate(o)))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().OrderBy(o => ClientEvalSelectorStateless()), + predicate: o => ClientEvalPredicate(o))); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_Count_with_predicate_client_eval_mixed(bool isAsync) + public virtual Task OrderBy_Count_with_predicate_client_eval_mixed(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Count( source: OrderBy( source: DbSet, keySelector: (o) => o.OrderID), predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().OrderBy(o => o.OrderID), - predicate: o => ClientEvalPredicate(o)))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().OrderBy(o => o.OrderID), + predicate: o => ClientEvalPredicate(o))); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_Where_Count_with_predicate_client_eval(bool isAsync) + public virtual Task OrderBy_Where_Count_with_predicate_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: OrderBy( source: DbSet, keySelector: (o) => 42), predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().OrderBy(o => ClientEvalSelectorStateless()).Where(o => ClientEvalPredicate(o)), - predicate: o => ClientEvalPredicate(o)))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().OrderBy(o => ClientEvalSelectorStateless()).Where(o => ClientEvalPredicate(o)), + predicate: o => ClientEvalPredicate(o))); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_Where_Count_with_predicate_client_eval_mixed(bool isAsync) + public virtual Task OrderBy_Where_Count_with_predicate_client_eval_mixed(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: OrderBy( source: DbSet, keySelector: (o) => o.OrderID), predicate: (o) => ClientEvalPredicate(o))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertCount( - isAsync, - ss => ss.Set().OrderBy(o => o.OrderID).Where(o => ClientEvalPredicate(o)), - predicate: o => o.CustomerID != "ALFKI"))).Message)); + return AssertTranslationFailed( + () => AssertCount( + isAsync, + ss => ss.Set().OrderBy(o => o.OrderID).Where(o => ClientEvalPredicate(o)), + predicate: o => o.CustomerID != "ALFKI")); } [ConditionalTheory] @@ -1052,17 +1024,13 @@ public virtual Task Last(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Last_when_no_order_by(bool isAsync) + public virtual Task Last_when_no_order_by(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - @"Last(Where( source: DbSet, predicate: (c) => c.CustomerID == ""ALFKI""))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertLast( - isAsync, - ss => ss.Set().Where(c => c.CustomerID == "ALFKI"), - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertLast( + isAsync, + ss => ss.Set().Where(c => c.CustomerID == "ALFKI"), + entryCount: 1)); } [ConditionalTheory] @@ -1396,40 +1364,32 @@ public virtual Task Contains_top_level(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Contains_with_local_tuple_array_closure(bool isAsync) + public virtual Task Contains_with_local_tuple_array_closure(bool isAsync) { var ids = new[] { Tuple.Create(1, 2), Tuple.Create(10248, 11) }; - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (o) => Contains>( source: (Unhandled parameter: __ids_0), value: new Tuple( o.OrderID, o.ProductID )))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(o => ids.Contains(new Tuple(o.OrderID, o.ProductID))), - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => ids.Contains(new Tuple(o.OrderID, o.ProductID))), + entryCount: 1)); } [ConditionalTheory(Skip = "Issue #15937")] [MemberData(nameof(IsAsyncData))] - public virtual async Task Contains_with_local_anonymous_type_array_closure(bool isAsync) + public virtual Task Contains_with_local_anonymous_type_array_closure(bool isAsync) { var ids = new[] { new { Id1 = 1, Id2 = 2 }, new { Id1 = 10248, Id2 = 11 } }; - Assert.Equal( - CoreStrings.TranslationFailed( - "(o) => Contains<<>f__AnonymousType0>( source: (Unhandled parameter: __ids_0), value: new { Id1 = o.OrderID, Id2 = o.ProductID })"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(o => ids.Contains(new { Id1 = o.OrderID, Id2 = o.ProductID })), - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => ids.Contains(new { Id1 = o.OrderID, Id2 = o.ProductID })), + entryCount: 1)); } - protected string RemoveNewLines(string message) - => message.Replace("\n", "").Replace("\r", ""); + //protected string RemoveNewLines(string message) + // => message.Replace("\n", "").Replace("\r", ""); [ConditionalFact] public virtual void OfType_Select() @@ -1628,13 +1588,16 @@ public virtual void Paging_operation_on_string_doesnt_issue_warning() { using (var context = CreateContext()) { + var message = Assert.Throws(() => context.Customers.Select(c => c.CustomerID.FirstOrDefault()).ToList()).Message; + Assert.Equal( CoreStrings.QueryFailed( - "AsQueryable(NavigationTreeExpression Value: EntityReferenceCustomer Expression: (Unhandled parameter: c).CustomerID)", + @"NavigationTreeExpression + Value: EntityReference: Customer + Expression: (Unhandled parameter: c).CustomerID + .AsQueryable()", "NavigationExpandingExpressionVisitor"), - RemoveNewLines( - Assert.Throws( - () => context.Customers.Select(c => c.CustomerID.FirstOrDefault()).ToList()).Message)); + message); } } diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs index 3e6ecfc2046..10d6fa42825 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs @@ -134,18 +134,15 @@ await AssertQuery( [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Select_bool_closure_with_order_by_property_with_cast_to_nullable(bool isAsync) + public virtual Task Select_bool_closure_with_order_by_property_with_cast_to_nullable(bool isAsync) { var boolean = false; - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy>( source: DbSet, keySelector: (c) => (Nullable)(Unhandled parameter: __p_0).f)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Select(c => new { f = boolean }).OrderBy(e => (bool?)e.f), - assertOrder: true))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Select(c => new { f = boolean }).OrderBy(e => (bool?)e.f), + assertOrder: true)); } [ConditionalTheory] diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs index b601844dfc4..5e68c7a0c42 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Where.cs @@ -581,16 +581,13 @@ where EF.Property(e, "Title") [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_client(bool isAsync) + public virtual Task Where_client(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(c => c.IsLondon), - entryCount: 6))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(c => c.IsLondon), + entryCount: 6)); } [ConditionalTheory] @@ -605,74 +602,61 @@ public virtual Task Where_subquery_correlated(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_subquery_correlated_client_eval(bool isAsync) + public virtual Task Where_subquery_correlated_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Any( source: DbSet, predicate: (c0) => EntityShaperExpression: EntityType: Customer ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False .CustomerID == c0.CustomerID && c0.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().OrderBy(c1 => c1.CustomerID).Take(5) - .Where(c1 => ss.Set().Any(c2 => c1.CustomerID == c2.CustomerID && c2.IsLondon)), - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set() + .OrderBy(c1 => c1.CustomerID) + .Take(5) + .Where(c1 => ss.Set().Any(c2 => c1.CustomerID == c2.CustomerID && c2.IsLondon)), + entryCount: 1)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_client_and_server_top_level(bool isAsync) + public virtual Task Where_client_and_server_top_level(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon && c.CustomerID != \"AROUT\")"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(c => c.IsLondon && c.CustomerID != "AROUT"), - entryCount: 5))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(c => c.IsLondon && c.CustomerID != "AROUT"), + entryCount: 5)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_client_or_server_top_level(bool isAsync) + public virtual Task Where_client_or_server_top_level(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon || c.CustomerID == \"ALFKI\")"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(c => c.IsLondon || c.CustomerID == "ALFKI"), - entryCount: 7))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(c => c.IsLondon || c.CustomerID == "ALFKI"), + entryCount: 7)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_client_and_server_non_top_level(bool isAsync) + public virtual Task Where_client_and_server_non_top_level(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.CustomerID != \"ALFKI\" == c.IsLondon && c.CustomerID != \"AROUT\")"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(c => c.CustomerID != "ALFKI" == (c.IsLondon && c.CustomerID != "AROUT")), - entryCount: 6))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(c => c.CustomerID != "ALFKI" == (c.IsLondon && c.CustomerID != "AROUT")), + entryCount: 6)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_client_deep_inside_predicate_and_server_top_level(bool isAsync) + public virtual Task Where_client_deep_inside_predicate_and_server_top_level(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.CustomerID != \"ALFKI\" && c.CustomerID == \"MAUMAR\" || c.CustomerID != \"AROUT\" && c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where( - c => c.CustomerID != "ALFKI" && (c.CustomerID == "MAUMAR" || (c.CustomerID != "AROUT" && c.IsLondon))), - entryCount: 5))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set() + .Where(c => c.CustomerID != "ALFKI" && (c.CustomerID == "MAUMAR" || (c.CustomerID != "AROUT" && c.IsLondon))), + entryCount: 5)); } [ConditionalTheory] @@ -1240,15 +1224,12 @@ public virtual Task Where_bool_member_false(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_bool_client_side_negated(bool isAsync) + public virtual Task Where_bool_client_side_negated(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (p) => !(ClientFunc(p.ProductID)) && p.Discontinued)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(p => !ClientFunc(p.ProductID) && p.Discontinued), entryCount: 8))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(p => !ClientFunc(p.ProductID) && p.Discontinued), entryCount: 8)); } private static bool ClientFunc(int id) diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs index 01e98709a57..b93dbe019b8 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.cs @@ -605,16 +605,13 @@ public virtual Task Queryable_simple_anonymous_subquery(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Queryable_reprojection(bool isAsync) + public virtual Task Queryable_reprojection(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().Where(c => c.IsLondon) - .Select(c => new Customer { CustomerID = "Foo", City = c.City })))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(c => c.IsLondon) + .Select(c => new Customer { CustomerID = "Foo", City = c.City }))); } [ConditionalTheory] @@ -1146,44 +1143,35 @@ public virtual Task All_top_level_subquery_ef_property(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task All_client(bool isAsync) + public virtual Task All_client(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("All( source: DbSet, predicate: (c) => c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertAll( - isAsync, - ss => ss.Set(), - predicate: c => c.IsLondon))).Message)); + return AssertTranslationFailed( + () => AssertAll( + isAsync, + ss => ss.Set(), + predicate: c => c.IsLondon)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task All_client_and_server_top_level(bool isAsync) + public virtual Task All_client_and_server_top_level(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("All( source: DbSet, predicate: (c) => c.CustomerID != \"Foo\" && c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertAll( - isAsync, - ss => ss.Set(), - predicate: c => c.CustomerID != "Foo" && c.IsLondon))).Message)); + return AssertTranslationFailed( + () => AssertAll( + isAsync, + ss => ss.Set(), + predicate: c => c.CustomerID != "Foo" && c.IsLondon)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task All_client_or_server_top_level(bool isAsync) + public virtual Task All_client_or_server_top_level(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("All( source: DbSet, predicate: (c) => c.CustomerID != \"Foo\" || c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertAll( - isAsync, - ss => ss.Set(), - predicate: c => c.CustomerID != "Foo" || c.IsLondon))).Message)); + return AssertTranslationFailed( + () => AssertAll( + isAsync, + ss => ss.Set(), + predicate: c => c.CustomerID != "Foo" || c.IsLondon)); } [ConditionalTheory] @@ -1235,26 +1223,25 @@ public virtual async Task Projection_when_arithmetic_mixed_subqueries(bool isAsy { Assert.Equal( "Unsupported Binary operator type specified.", - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => - from o in ss.Set().OrderBy(o => o.OrderID).Take(3).Select( - o2 => new { o2, Mod = o2.OrderID % 2 }) - from e in ss.Set().OrderBy(e => e.EmployeeID).Take(2).Select( - e2 => new { e2, Square = e2.EmployeeID ^ 2 }) - select new - { - Add = e.e2.EmployeeID + o.o2.OrderID, - e.Square, - e.e2, - Literal = 42, - o.o2, - o.Mod - }, - elementSorter: e => (e.e2.EmployeeID, e.o2.OrderID), - entryCount: 3))).Message)); + (await Assert.ThrowsAsync( + () => AssertQuery( + isAsync, + ss => + from o in ss.Set().OrderBy(o => o.OrderID).Take(3).Select( + o2 => new { o2, Mod = o2.OrderID % 2 }) + from e in ss.Set().OrderBy(e => e.EmployeeID).Take(2).Select( + e2 => new { e2, Square = e2.EmployeeID ^ 2 }) + select new + { + Add = e.e2.EmployeeID + o.o2.OrderID, + e.Square, + e.e2, + Literal = 42, + o.o2, + o.Mod + }, + elementSorter: e => (e.e2.EmployeeID, e.o2.OrderID), + entryCount: 3))).Message); } [ConditionalTheory] @@ -1293,17 +1280,14 @@ public virtual Task Cast_results_to_object(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task First_client_predicate(bool isAsync) + public virtual Task First_client_predicate(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: OrderBy( source: DbSet, keySelector: (c) => c.CustomerID), predicate: (c) => c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertFirst( - isAsync, - ss => ss.Set().OrderBy(c => c.CustomerID), - predicate: c => c.IsLondon, - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertFirst( + isAsync, + ss => ss.Set().OrderBy(c => c.CustomerID), + predicate: c => c.IsLondon, + entryCount: 1)); } [ConditionalTheory] @@ -2028,72 +2012,59 @@ public virtual Task Where_query_composition2_FirstOrDefault_with_anonymous(bool [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_query_composition3(bool isAsync) + public virtual Task Where_query_composition3(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: OrderBy( source: DbSet, keySelector: (c0) => c0.CustomerID), predicate: (c0) => c0.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c1 in ss.Set() - where c1.City == ss.Set().OrderBy(c => c.CustomerID).First(c => c.IsLondon).City - select c1, - entryCount: 6))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c1 in ss.Set() + where c1.City == ss.Set().OrderBy(c => c.CustomerID).First(c => c.IsLondon).City + select c1, + entryCount: 6)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_query_composition4(bool isAsync) + public virtual Task Where_query_composition4(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c1) => c1.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c1 in ss.Set().OrderBy(c => c.CustomerID).Take(2) - where c1.City == (from c2 in ss.Set().OrderBy(c => c.CustomerID) - from c3 in ss.Set().OrderBy(c => c.IsLondon).ThenBy(c => c.CustomerID) - select new { c3 }).First().c3.City - select c1, - entryCount: 1))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c1 in ss.Set().OrderBy(c => c.CustomerID).Take(2) + where c1.City == (from c2 in ss.Set().OrderBy(c => c.CustomerID) + from c3 in ss.Set().OrderBy(c => c.IsLondon).ThenBy(c => c.CustomerID) + select new { c3 }).First().c3.City + select c1, + entryCount: 1)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_query_composition5(bool isAsync) + public virtual Task Where_query_composition5(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (c) => c.IsLondon == First(Select( source: OrderBy( source: DbSet, keySelector: (c0) => c0.CustomerID), selector: (c0) => c0.IsLondon)))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c1 in ss.Set() - where c1.IsLondon == ss.Set().OrderBy(c => c.CustomerID).First().IsLondon - select c1, - entryCount: 85))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c1 in ss.Set() + where c1.IsLondon == ss.Set().OrderBy(c => c.CustomerID).First().IsLondon + select c1, + entryCount: 85)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Where_query_composition6(bool isAsync) + public virtual Task Where_query_composition6(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (c) => c.IsLondon == First(Select( source: OrderBy( source: DbSet, keySelector: (c0) => c0.CustomerID), selector: (c0) => c0.IsLondon)))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from c1 in ss.Set() - where c1.IsLondon - == ss.Set().OrderBy(c => c.CustomerID) - .Select(c => new { Foo = c }) - .First().Foo.IsLondon - select c1, - entryCount: 85))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c1 in ss.Set() + where c1.IsLondon + == ss.Set().OrderBy(c => c.CustomerID) + .Select(c => new { Foo = c }) + .First().Foo.IsLondon + select c1, + entryCount: 85)); } [ConditionalTheory] @@ -2129,18 +2100,16 @@ public virtual Task OrderBy_scalar_primitive(bool isAsync) public virtual async Task SelectMany_mixed(bool isAsync) { Assert.Equal( - CoreStrings.QueryFailed("(e1) => string[] { \"a\", \"b\", }", "NavigationExpandingExpressionVisitor"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => - from e1 in ss.Set().OrderBy(e => e.EmployeeID).Take(2) - from s in new[] { "a", "b" } - from c in ss.Set().OrderBy(c => c.CustomerID).Take(2) - select new { e1, s, c }, - e => (e.e1.EmployeeID, e.c.CustomerID), - entryCount: 4))).Message)); + CoreStrings.QueryFailed("e1 => string[] { \"a\", \"b\", }", "NavigationExpandingExpressionVisitor"), + (await Assert.ThrowsAsync( + () => AssertQuery( + isAsync, + ss => from e1 in ss.Set().OrderBy(e => e.EmployeeID).Take(2) + from s in new[] { "a", "b" } + from c in ss.Set().OrderBy(c => c.CustomerID).Take(2) + select new { e1, s, c }, + e => (e.e1.EmployeeID, e.c.CustomerID), + entryCount: 4))).Message); } [ConditionalTheory] @@ -2532,33 +2501,39 @@ public virtual Task Default_if_empty_top_level_followed_by_projecting_constant(b [MemberData(nameof(IsAsyncData))] public virtual async Task Default_if_empty_top_level_arg(bool isAsync) { + var message = (await Assert.ThrowsAsync( + () => AssertQuery( + isAsync, + ss => from e in ss.Set().Where(c => c.EmployeeID == NonExistentID).DefaultIfEmpty(new Employee()) + select e, + entryCount: 1))).Message; + Assert.Equal( CoreStrings.QueryFailed( - "DefaultIfEmpty( source: Where( source: DbSet, predicate: (c) => c.EmployeeID == 4294967295), defaultValue: (Unhandled parameter: __p_0))", + @"DbSet + .Where(c => c.EmployeeID == 4294967295) + .DefaultIfEmpty((Unhandled parameter: __p_0))", "NavigationExpandingExpressionVisitor"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from e in ss.Set().Where(c => c.EmployeeID == NonExistentID).DefaultIfEmpty(new Employee()) - select e, - entryCount: 1))).Message)); + message); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Default_if_empty_top_level_arg_followed_by_projecting_constant(bool isAsync) { + var message = (await Assert.ThrowsAsync( + () => AssertQueryScalar( + isAsync, + ss => from e in ss.Set().Where(c => c.EmployeeID == NonExistentID).DefaultIfEmpty(new Employee()) + select 42))).Message; + Assert.Equal( CoreStrings.QueryFailed( - "DefaultIfEmpty( source: Where( source: DbSet, predicate: (c) => c.EmployeeID == 4294967295), defaultValue: (Unhandled parameter: __p_0))", + @"DbSet + .Where(c => c.EmployeeID == 4294967295) + .DefaultIfEmpty((Unhandled parameter: __p_0))", "NavigationExpandingExpressionVisitor"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQueryScalar( - isAsync, - ss => from e in ss.Set().Where(c => c.EmployeeID == NonExistentID).DefaultIfEmpty(new Employee()) - select 42))).Message)); + message); } [ConditionalTheory] @@ -2702,34 +2677,27 @@ public virtual Task OrderBy_anon2(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_client_mixed(bool isAsync) + public virtual Task OrderBy_client_mixed(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => c.IsLondon)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => ss.Set().OrderBy(c => c.IsLondon).ThenBy(c => c.CompanyName), - assertOrder: true, - entryCount: 91))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().OrderBy(c => c.IsLondon).ThenBy(c => c.CompanyName), + assertOrder: true, + entryCount: 91)); } [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task OrderBy_multiple_queries(bool isAsync) + public virtual Task OrderBy_multiple_queries(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Join>( outer: DbSet, inner: DbSet, outerKeySelector: (c) => new Foo{ Bar = c.CustomerID } , innerKeySelector: (o) => new Foo{ Bar = o.CustomerID } , resultSelector: (c, o) => new TransparentIdentifier( Outer = c, Inner = o ))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => - from c in ss.Set() - join o in ss.Set() on new Foo { Bar = c.CustomerID } equals new Foo { Bar = o.CustomerID } - orderby c.IsLondon, o.OrderDate - select new { c, o }))).Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from c in ss.Set() + join o in ss.Set() on new Foo { Bar = c.CustomerID } equals new Foo { Bar = o.CustomerID } + orderby c.IsLondon, o.OrderDate + select new { c, o })); } [ConditionalTheory] @@ -3547,94 +3515,64 @@ await AssertQuery( entryCount: 267); } - [ConditionalFact] - public virtual void Random_next_is_not_funcletized_1() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Random_next_is_not_funcletized_1(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (o) => o.OrderID > new Random().Next())"), - RemoveNewLines( - Assert.Throws( - () => context.Orders - .Where(o => o.OrderID > new Random().Next()) - .ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => o.OrderID > new Random().Next()))); } - [ConditionalFact] - public virtual void Random_next_is_not_funcletized_2() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Random_next_is_not_funcletized_2(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (o) => o.OrderID > new Random().Next(5))"), - RemoveNewLines( - Assert.Throws( - () => context.Orders - .Where(o => o.OrderID > new Random().Next(5)) - .ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => o.OrderID > new Random().Next(5)))); } - [ConditionalFact] - public virtual void Random_next_is_not_funcletized_3() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Random_next_is_not_funcletized_3(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (o) => o.OrderID > new Random().Next( minValue: 0, maxValue: 10))"), - RemoveNewLines( - Assert.Throws( - () => context.Orders - .Where(o => o.OrderID > new Random().Next(0, 10)) - .ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => o.OrderID > new Random().Next(0, 10)))); } - [ConditionalFact] - public virtual void Random_next_is_not_funcletized_4() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Random_next_is_not_funcletized_4(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (o) => o.OrderID > new Random(15).Next())"), - RemoveNewLines( - Assert.Throws( - () => context.Orders - .Where(o => o.OrderID > new Random(15).Next()) - .ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => o.OrderID > new Random(15).Next()))); } - [ConditionalFact] - public virtual void Random_next_is_not_funcletized_5() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Random_next_is_not_funcletized_5(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (o) => o.OrderID > new Random(15).Next(5))"), - RemoveNewLines( - Assert.Throws( - () => context.Orders - .Where(o => o.OrderID > new Random(15).Next(5)) - .ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => o.OrderID > new Random(15).Next(5)))); } - [ConditionalFact] - public virtual void Random_next_is_not_funcletized_6() + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Random_next_is_not_funcletized_6(bool isAsync) { - using (var context = CreateContext()) - { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (o) => o.OrderID > new Random(15).Next( minValue: 0, maxValue: 10))"), - RemoveNewLines( - Assert.Throws( - () => context.Orders - .Where(o => o.OrderID > new Random(15).Next(0, 10)) - .ToList()).Message)); - } + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => ss.Set().Where(o => o.OrderID > new Random(15).Next(0, 10)))); } [ConditionalTheory] @@ -5361,18 +5299,15 @@ public virtual Task Let_entity_equality_to_other_entity(bool isAsync) [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task SelectMany_after_client_method(bool isAsync) + public virtual Task SelectMany_after_client_method(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => ClientOrderBy(c))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQueryScalar( - isAsync, - ss => ss.Set().OrderBy(c => ClientOrderBy(c)) - .SelectMany(c => c.Orders) - .Distinct() - .Select(o => o.OrderDate)))).Message)); + return AssertTranslationFailed( + () => AssertQueryScalar( + isAsync, + ss => ss.Set().OrderBy(c => ClientOrderBy(c)) + .SelectMany(c => c.Orders) + .Distinct() + .Select(o => o.OrderDate))); } private static string ClientOrderBy(Customer c) @@ -5420,23 +5355,18 @@ select g.OrderByDescending(x => x.OrderID), [ConditionalTheory] [MemberData(nameof(IsAsyncData))] - public virtual async Task Client_OrderBy_GroupBy_Group_ordering_works(bool isAsync) + public virtual Task Client_OrderBy_GroupBy_Group_ordering_works(bool isAsync) { - Assert.StartsWith( - "The LINQ expression ", - RemoveNewLines( - (await Assert.ThrowsAsync( - () => AssertQuery( - isAsync, - ss => from o in ss.Set() - orderby ClientEvalSelector(o) - group o by o.CustomerID - into g - orderby g.Key - select g.OrderByDescending(x => x.OrderID), - assertOrder: true, - elementAsserter: (e, a) => AssertCollection(e, a, ordered: true)))) - .Message)); + return AssertTranslationFailed( + () => AssertQuery( + isAsync, + ss => from o in ss.Set() + orderby ClientEvalSelector(o) + group o by o.CustomerID into g + orderby g.Key + select g.OrderByDescending(x => x.OrderID), + assertOrder: true, + elementAsserter: (e, a) => AssertCollection(e, a, ordered: true))); } [ConditionalTheory] @@ -5616,6 +5546,13 @@ public virtual Task AsQueryable_in_query_server_evals(bool isAsync) elementAsserter: (e, a) => AssertCollection(e, a, ordered: true)); } + protected async Task AssertTranslationFailed(Func testCode) + { + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + (await Assert.ThrowsAsync(testCode)).Message); + } + private static Expression> ValidYear => a => a.OrderDate.Value.Year == 1998; } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs index f0072880313..18041faed6b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/QueryLoggingSqlServerTest.cs @@ -38,7 +38,7 @@ var customers Assert.NotNull(customers); Assert.StartsWith( - "(queryContext) => new QueryingEnumerable(", + "queryContext => new QueryingEnumerable(", Fixture.TestSqlLoggerFactory.Log[0].Message); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs index 6dfc3fad776..7087beceb63 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs @@ -1048,13 +1048,9 @@ FROM [Customers] AS [c] WHERE [c].[CustomerID] = N'FISSA'"); } - public override async Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool isAsync) + public override Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => new CustomerListItem( c.CustomerID, c.City ).City)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync))).Message)); + return AssertTranslationFailed(() => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync)); } public override async Task Filtered_collection_projection_is_tracked(bool isAsync) diff --git a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs index 987c52a527c..8e18f1323f2 100644 --- a/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/BuiltInDataTypesSqliteTest.cs @@ -884,40 +884,25 @@ public virtual void Cant_query_Min_of_converted_types() .Select(g => g.Min(e => e.TestNullableDecimal)) .ToList()); - Assert.Equal( - CoreStrings.TranslationFailed( - "Min( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableDecimal)"), - RemoveNewLines(ex.Message)); + AssertTranslationFailed( + () => query + .Select(g => g.Min(e => e.TestNullableDecimal)) + .ToList()); - ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Min(e => e.TestNullableDateTimeOffset)) .ToList()); - Assert.Equal( - CoreStrings.TranslationFailed( - "Min>( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableDateTimeOffset)"), - RemoveNewLines(ex.Message)); - - ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Min(e => e.TestNullableTimeSpan)) .ToList()); - Assert.Equal( - CoreStrings.TranslationFailed( - "Min>( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableTimeSpan)"), - RemoveNewLines(ex.Message)); - - ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Min(e => e.TestNullableUnsignedInt64)) .ToList()); - - Assert.Equal( - CoreStrings.TranslationFailed( - "Min>( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableUnsignedInt64)"), - RemoveNewLines(ex.Message)); } } @@ -954,45 +939,25 @@ public virtual void Cant_query_Max_of_converted_types() .Where(e => e.PartitionId == 201) .GroupBy(_ => true); - var ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Max(e => e.TestNullableDecimal)) .ToList()); - Assert.Equal( - CoreStrings.TranslationFailed( - "Max( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableDecimal)"), - RemoveNewLines(ex.Message)); - - ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Max(e => e.TestNullableDateTimeOffset)) .ToList()); - Assert.Equal( - CoreStrings.TranslationFailed( - "Max>( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableDateTimeOffset)"), - RemoveNewLines(ex.Message)); - - ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Max(e => e.TestNullableTimeSpan)) .ToList()); - Assert.Equal( - CoreStrings.TranslationFailed( - "Max>( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableTimeSpan)"), - RemoveNewLines(ex.Message)); - - ex = Assert.Throws( + AssertTranslationFailed( () => query .Select(g => g.Max(e => e.TestNullableUnsignedInt64)) .ToList()); - - Assert.Equal( - CoreStrings.TranslationFailed( - "Max>( source: GroupByShaperExpression: KeySelector: 1, ElementSelector:EntityShaperExpression: EntityType: BuiltInNullableDataTypes ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , selector: (e) => e.TestNullableUnsignedInt64)"), - RemoveNewLines(ex.Message)); } } @@ -1009,14 +974,10 @@ public virtual void Cant_query_Average_of_converted_types() context.SaveChanges(); - var ex = Assert.Throws( + AssertTranslationFailed( () => context.Set() .Where(e => e.PartitionId == 202) .Average(e => e.TestNullableDecimal)); - Assert.Equal( - CoreStrings.TranslationFailed( - "Average( source: Where( source: DbSet, predicate: (b) => b.PartitionId == 202), selector: (b) => b.TestNullableDecimal)"), - RemoveNewLines(ex.Message)); } } @@ -1033,19 +994,19 @@ public virtual void Cant_query_Sum_of_converted_types() context.SaveChanges(); - var ex = Assert.Throws( + AssertTranslationFailed( () => context.Set() .Where(e => e.PartitionId == 203) .Sum(e => e.TestDecimal)); - Assert.Equal( - CoreStrings.TranslationFailed( - "Sum( source: Where( source: DbSet, predicate: (b) => b.PartitionId == 203), selector: (b) => b.TestDecimal)"), - RemoveNewLines(ex.Message)); } } - private string RemoveNewLines(string message) - => message.Replace("\n", "").Replace("\r", ""); + private void AssertTranslationFailed(Action testCode) + { + Assert.Contains( + CoreStrings.TranslationFailed("").Substring(21), + Assert.Throws(testCode).Message); + } [ConditionalFact] public virtual void Can_query_negation_of_converted_types() diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 8f16bc1a498..e7946d0ebcb 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -17,130 +17,77 @@ public GearsOfWarQuerySqliteTest(GearsOfWarQuerySqliteFixture fixture) } // SQLite client-eval - public override async Task Where_datetimeoffset_date_component(bool isAsync) + public override Task Where_datetimeoffset_date_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Date > (Unhandled parameter: __Date_0))"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_date_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_date_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_day_component(bool isAsync) + public override Task Where_datetimeoffset_day_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Day == 2)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_day_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_date_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_dayofyear_component(bool isAsync) + public override Task Where_datetimeoffset_dayofyear_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.DayOfYear == 2)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_dayofyear_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_dayofyear_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_hour_component(bool isAsync) + public override Task Where_datetimeoffset_hour_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Hour == 10)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_hour_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_hour_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_millisecond_component(bool isAsync) + public override Task Where_datetimeoffset_millisecond_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Millisecond == 0)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_millisecond_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_millisecond_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_minute_component(bool isAsync) + public override Task Where_datetimeoffset_minute_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Minute == 0)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_minute_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_minute_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_month_component(bool isAsync) + public override Task Where_datetimeoffset_month_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Month == 1)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_month_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_month_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_now(bool isAsync) + public override Task Where_datetimeoffset_now(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline != DateTimeOffset.Now)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_now(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_now(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_second_component(bool isAsync) + public override Task Where_datetimeoffset_second_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Second == 0)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_second_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_second_component(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_utcnow(bool isAsync) + public override Task Where_datetimeoffset_utcnow(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline != DateTimeOffset.UtcNow)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_utcnow(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_utcnow(isAsync)); } // SQLite client-eval - public override async Task Where_datetimeoffset_year_component(bool isAsync) + public override Task Where_datetimeoffset_year_component(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("Where( source: DbSet, predicate: (m) => m.Timeline.Year == 2)"), - RemoveNewLines((await Assert.ThrowsAsync( - () => base.Where_datetimeoffset_year_component(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.Where_datetimeoffset_year_component(isAsync)); } // SQLite client-eval - public override async Task DateTimeOffset_Contains_Less_than_Greater_than(bool isAsync) + public override Task DateTimeOffset_Contains_Less_than_Greater_than(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed( - "Where( source: DbSet, predicate: (m) => (Unhandled parameter: __start_0) <= (DateTimeOffset)m.Timeline.Date && m.Timeline < (Unhandled parameter: __end_1) && Contains( source: (Unhandled parameter: __dates_2), value: m.Timeline))"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => base.DateTimeOffset_Contains_Less_than_Greater_than(isAsync))) - .Message)); + return AssertTranslationFailed(() => base.DateTimeOffset_Contains_Less_than_Greater_than(isAsync)); } - private string RemoveNewLines(string message) - => message.Replace("\n", "").Replace("\r", ""); - // Sqlite does not support cross/outer apply public override Task Correlated_collections_inner_subquery_predicate_references_outer_qsre(bool isAsync) => null; diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs index 499e7c3040e..fdcf854e35e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/SimpleQuerySqliteTest.cs @@ -1332,13 +1332,9 @@ public override Task Like_with_non_string_column_using_ToString(bool isAsync) return base.Like_with_non_string_column_using_ToString(isAsync); } - public override async Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool isAsync) + public override Task Member_binding_after_ctor_arguments_fails_with_client_eval(bool isAsync) { - Assert.Equal( - CoreStrings.TranslationFailed("OrderBy( source: DbSet, keySelector: (c) => new CustomerListItem( c.CustomerID, c.City ).City)"), - RemoveNewLines( - (await Assert.ThrowsAsync( - () => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync))).Message)); + return AssertTranslationFailed(() => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync)); } [ConditionalTheory(Skip = "Issue#17230")] diff --git a/test/EFCore.Tests/Query/ExpressionPrinterTest.cs b/test/EFCore.Tests/Query/ExpressionPrinterTest.cs new file mode 100644 index 00000000000..915cbe5a609 --- /dev/null +++ b/test/EFCore.Tests/Query/ExpressionPrinterTest.cs @@ -0,0 +1,169 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using System.Linq.Expressions; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Xunit; + +namespace Microsoft.EntityFrameworkCore.Query +{ + public class ExpressionPrinterTest + { + private readonly ExpressionPrinter _expressionPrinter = new ExpressionPrinter(); + + [ConditionalFact] + public void UnaryExpression_printed_correctly() + { + Assert.Equal("(decimal)42", _expressionPrinter.Print(Expression.Convert(Expression.Constant(42), typeof(decimal)))); + Assert.Equal("throw \"Some exception\"", _expressionPrinter.Print(Expression.Throw(Expression.Constant("Some exception")))); + Assert.Equal("!(True)", _expressionPrinter.Print(Expression.Not(Expression.Constant(true)))); + Assert.Equal("(BaseClass as DerivedClass)", _expressionPrinter.Print(Expression.TypeAs(Expression.Constant(new BaseClass()), typeof(DerivedClass)))); + } + + private class BaseClass + { + } + + private class DerivedClass : BaseClass + { + } + + [ConditionalFact] + public void BinaryExpression_printed_correctly() + { + Assert.Equal("7 == 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Equal, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 != 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.NotEqual, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 > 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.GreaterThan, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 >= 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.GreaterThanOrEqual, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 < 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.LessThan, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 <= 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.LessThanOrEqual, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("True && True", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.AndAlso, Expression.Constant(true), Expression.Constant(true)))); + Assert.Equal("True || True", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.OrElse, Expression.Constant(true), Expression.Constant(true)))); + Assert.Equal("7 & 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.And, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 | 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Or, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 ^ 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.ExclusiveOr, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 + 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Add, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 - 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Subtract, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 * 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 / 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(7), Expression.Constant(42)))); + Assert.Equal("7 % 42", _expressionPrinter.Print(Expression.MakeBinary(ExpressionType.Modulo, Expression.Constant(7), Expression.Constant(42)))); + } + + [ConditionalFact] + public void ConditionalExpression_printed_correctly() + { + Assert.Equal( + "True ? \"Foo\" : \"Bar\"", + _expressionPrinter.Print( + Expression.Condition( + Expression.Constant(true), + Expression.Constant("Foo"), + Expression.Constant("Bar")))); + } + + [ConditionalFact] + public void Simple_lambda_printed_correctly() + { + Assert.Equal( + "prm => 42", + _expressionPrinter.Print( + Expression.Lambda( + Expression.Constant(42), + Expression.Parameter(typeof(int), "prm")))); + } + + [ConditionalFact] + public void Multi_parameter_lambda_printed_correctly() + { + Assert.Equal( + "(prm1, prm2) => 42", + _expressionPrinter.Print( + Expression.Lambda( + Expression.Constant(42), + Expression.Parameter(typeof(int), "prm1"), + Expression.Parameter(typeof(int), "prm2")))); + } + + [ConditionalFact] + public void Unhandled_parameter_in_lambda_detected() + { + Assert.Equal( + "prm1 => (Unhandled parameter: prm2)", + _expressionPrinter.Print( + Expression.Lambda( + Expression.Parameter(typeof(int), "prm2"), + Expression.Parameter(typeof(int), "prm1")))); + } + + [ConditionalFact] + public void MemberAccess_after_BinaryExpression_adds_parentheses() + { + Assert.Equal( + @"(7 + 42).Value", + _expressionPrinter.Print( + Expression.Property( + Expression.Add( + Expression.Constant(7, typeof(int?)), + Expression.Constant(42, typeof(int?))), + "Value"))); + } + + [ConditionalFact] + public void Simple_MethodCall_printed_correctly() + { + Assert.Equal( + @"""Foo"".ToUpper()", + _expressionPrinter.Print( + Expression.Call( + Expression.Constant("Foo"), + typeof(string).GetMethods().Single(m => m.Name == nameof(string.ToUpper) && m.GetParameters().Count() == 0)))); + } + + [ConditionalFact] + public void Complex_MethodCall_printed_correctly() + { + Assert.Equal( + @"""Foobar"".Substring( + startIndex: 0, + length: 4)", + _expressionPrinter.Print( + Expression.Call( + Expression.Constant("Foobar"), + typeof(string).GetMethods().Single(m => m.Name == nameof(string.Substring) && m.GetParameters().Count() == 2), + Expression.Constant(0), + Expression.Constant(4)))); + } + + [ConditionalFact] + public void Linq_methods_printed_as_extensions() + { + Expression> expr = + _ => new[] { 1, 2, 3 }.AsQueryable().Select(x => x.ToString()).AsEnumerable().Where(x => x.Length > 1); + + Assert.Equal( + @"new int[] +{ + 1, + 2, + 3 +} + .AsQueryable() + .Select(x => x.ToString()) + .AsEnumerable() + .Where(x => x.Length > 1)", + _expressionPrinter.Print(expr.Body)); + } + + [ConditionalFact] + public void Use_Print_method_when_printing_extension_expression() + { + var expr = new NullConditionalExpression( + Expression.Constant("caller"), + Expression.Constant("accessOperation")); + + Assert.Equal(expr.Print(), _expressionPrinter.Print(expr)); + } + } +}