Skip to content

Commit

Permalink
Adding tests for previously fixed issues
Browse files Browse the repository at this point in the history
Resolves #12274
Resolves #11835
Resolves #12597
Resolves #12379
Resolves #12717
Resolves #17775
Resolves #18962
  • Loading branch information
maumar committed Sep 21, 2020
1 parent a9871fe commit 3183f95
Show file tree
Hide file tree
Showing 11 changed files with 330 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ public NorthwindAsyncSimpleQueryInMemoryTest(NorthwindQueryInMemoryFixture<NoopM
{
}

// InMemory can throw server side exception
public override Task Average_on_nav_subquery_in_projection()
{
return Assert.ThrowsAsync<InvalidOperationException>(() => base.Average_on_nav_subquery_in_projection());
}

// mapping to view not supported on InMemory
public override Task Query_backed_by_database_view()
=> Task.CompletedTask;
Expand Down
38 changes: 38 additions & 0 deletions test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7860,6 +7860,44 @@ public virtual Task FirstOrDefault_over_int_compared_to_zero(bool async)
elementSorter: e => e);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Correlated_collection_with_inner_collection_references_element_two_levels_up(bool async)
{
return AssertQuery(
async,
ss => from o in ss.Set<Gear>().OfType<Officer>()
select new
{
o.FullName,
Collection = (from r in o.Reports
select new
{
ReportName = r.FullName,
OfficerName = o.FullName
}).ToList()
},
elementSorter: e => e.FullName,
elementAsserter: (e, a) =>
{
Assert.Equal(e.FullName, a.FullName);
AssertCollection(e.Collection, a.Collection, elementSorter: ee => (ee.OfficerName, ee.ReportName));
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task Accessing_derived_property_using_hard_and_soft_cast(bool async)
{
await AssertQuery(
async,
ss => ss.Set<LocustLeader>().Where(ll => ll is LocustCommander && ((LocustCommander)ll).HighCommandId != 0));

await AssertQuery(
async,
ss => ss.Set<LocustLeader>().Where(ll => ll is LocustCommander && (ll as LocustCommander).HighCommandId != 0));
}

protected GearsOfWarContext CreateContext()
=> Fixture.CreateContext();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1986,5 +1986,18 @@ public virtual Task Min_after_default_if_empty_does_not_throw(bool isAsync)
isAsync,
ss => ss.Set<Order>().Where(o => o.OrderID == 10243).Select(o => o.OrderID).DefaultIfEmpty());
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Average_on_nav_subquery_in_projection(bool isAsync)
{
return AssertQuery(
isAsync,
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => new { Ave = c.Orders.Average(o => o.OrderID) }),
assertOrder: true,
elementAsserter: (e, a) => Assert.InRange(e.Ave - a.Ave, -0.1D, 0.1D));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,6 @@ var results
Assert.Equal(830, results.SelectMany(a => a.Orders).ToList().Count);
}

[ConditionalFact(Skip = "Issue #17775")]
public virtual async Task Average_on_nav_subquery_in_projection()
{
using var context = CreateContext();
var results
= await context.Customers.Select(
c => new { Ave = c.Orders.Average(o => o.OrderID) })
.ToListAsync();

Assert.Equal(91, results.ToList().Count);
}

[ConditionalFact]
public virtual async Task ToListAsync_can_be_canceled()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6326,5 +6326,15 @@ public virtual Task First_on_collection_in_projection(bool async)
Assert.Equal(e.OrderDate, a.OrderDate);
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task SkipWhile_throws_meaningful_exception(bool async)
{
return AssertTranslationFailed(
() => AssertQuery(
async,
ss => ss.Set<Customer>().OrderBy(c => c.CustomerID).SkipWhile(c => c.CustomerID != "Foo").Skip(1)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1845,5 +1845,20 @@ public virtual Task Custom_projection_reference_navigation_PK_to_FK_optimization
AssertEqual(e.Customer, a.Customer);
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projecting_Length_of_a_string_property_after_FirstOrDefault_on_correlated_collection(bool async)
{
return AssertQueryScalar(
async,
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => (int?)c.Orders.OrderBy(o => o.OrderID).Select(o => o.CustomerID).FirstOrDefault().Length),
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => c.Orders.OrderBy(o => o.OrderID).Select(o => o.CustomerID).FirstOrDefault().MaybeScalar(x => x.Length)),
assertOrder: true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7159,6 +7159,37 @@ FROM [Gears] AS [g]
WHERE ([s].[Id] = [g].[SquadId]) AND ([g].[HasSoulPatch] = CAST(1 AS bit))), 0) <> 0)");
}

public override async Task Correlated_collection_with_inner_collection_references_element_two_levels_up(bool async)
{
await base.Correlated_collection_with_inner_collection_references_element_two_levels_up(async);

AssertSql(
@"SELECT [g].[FullName], [g].[Nickname], [g].[SquadId], [t].[ReportName], [t].[OfficerName], [t].[Nickname], [t].[SquadId]
FROM [Gears] AS [g]
LEFT JOIN [Officers] AS [o] ON ([g].[Nickname] = [o].[Nickname]) AND ([g].[SquadId] = [o].[SquadId])
OUTER APPLY (
SELECT [g0].[FullName] AS [ReportName], [g].[FullName] AS [OfficerName], [g0].[Nickname], [g0].[SquadId]
FROM [Gears] AS [g0]
WHERE ([g].[Nickname] = [g0].[LeaderNickname]) AND ([g].[SquadId] = [g0].[LeaderSquadId])
) AS [t]
WHERE [o].[Nickname] IS NOT NULL
ORDER BY [g].[Nickname], [g].[SquadId], [t].[Nickname], [t].[SquadId]");
}

public override async Task Accessing_derived_property_using_hard_and_soft_cast(bool async)
{
await base.Accessing_derived_property_using_hard_and_soft_cast(async);

AssertSql(
@"SELECT [l].[Name], [l].[Discriminator], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l].[DefeatedByNickname], [l].[DefeatedBySquadId], [l].[HighCommandId]
FROM [LocustLeaders] AS [l]
WHERE ([l].[Discriminator] = N'LocustCommander') AND (([l].[HighCommandId] <> 0) OR [l].[HighCommandId] IS NULL)",
//
@"SELECT [l].[Name], [l].[Discriminator], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l].[DefeatedByNickname], [l].[DefeatedBySquadId], [l].[HighCommandId]
FROM [LocustLeaders] AS [l]
WHERE ([l].[Discriminator] = N'LocustCommander') AND (([l].[HighCommandId] <> 0) OR [l].[HighCommandId] IS NULL)");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,14 @@ public override async Task Count_on_projection_with_client_eval(bool async)
FROM [Orders] AS [o]");
}

public override async Task Average_on_nav_subquery_in_projection(bool isAsync)
{
await base.Average_on_nav_subquery_in_projection(isAsync);

AssertSql(
@"");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,20 @@ FROM [Orders] AS [o]
LEFT JOIN [Customers] AS [c] ON [o].[CustomerID] = [c].[CustomerID]");
}

public override async Task Projecting_Length_of_a_string_property_after_FirstOrDefault_on_correlated_collection(bool async)
{
await base.Projecting_Length_of_a_string_property_after_FirstOrDefault_on_correlated_collection(async);

AssertSql(
@"SELECT (
SELECT TOP(1) CAST(LEN([o].[CustomerID]) AS int)
FROM [Orders] AS [o]
WHERE [c].[CustomerID] = [o].[CustomerID]
ORDER BY [o].[OrderID])
FROM [Customers] AS [c]
ORDER BY [c].[CustomerID]");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);

Expand Down
164 changes: 164 additions & 0 deletions test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
Expand All @@ -23,6 +24,7 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ModelSnapshot22;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -9139,6 +9141,168 @@ private SqlServerTestStore CreateDatabase22568()

#endregion

#region Issue12274

[ConditionalFact]
public virtual void Parameterless_ctor_on_inner_DTO_gets_called_for_every_row()
{
using (CreateDatabase12274())
{
using var context = new MyContext12274(_options);
var results = context.Entities.Select(x => new OuterDTO12274 { Id = x.Id, Name = x.Name, Inner = new InnerDTO12274() }).ToList();
Assert.Equal(4, results.Count);
Assert.False(ReferenceEquals(results[0].Inner, results[1].Inner));
Assert.False(ReferenceEquals(results[1].Inner, results[2].Inner));
Assert.False(ReferenceEquals(results[2].Inner, results[3].Inner));
}
}

private class MyContext12274 : DbContext
{
public DbSet<MyEntity12274> Entities { get; set; }

public MyContext12274(DbContextOptions options)
: base(options)
{
}
}

public class MyEntity12274
{
public int Id { get; set; }
public string Name { get; set; }
}

public class OuterDTO12274
{
public int Id { get; set; }
public string Name { get; set; }
public InnerDTO12274 Inner { get; set; }
}

public class InnerDTO12274
{
public InnerDTO12274()
{
}
}

private SqlServerTestStore CreateDatabase12274()
=> CreateTestStore(
() => new MyContext12274(_options),
context =>
{
var e1 = new MyEntity12274 { Name = "1" };
var e2 = new MyEntity12274 { Name = "2" };
var e3 = new MyEntity12274 { Name = "3" };
var e4 = new MyEntity12274 { Name = "4" };
context.Entities.AddRange(e1, e2, e3, e4);
context.SaveChanges();
ClearLog();
});

#endregion

#region Issue11835

[ConditionalFact]
public virtual void Projecting_correlated_collection_along_with_non_mapped_property()
{
using (CreateDatabase11835())
{
using var context = new MyContext11835(_options);
var result = context.Blogs.Select(
e => new
{
Id = e.Id,
Title = e.Title,
FirstPostName = e.Posts.Where(i => i.Name.Contains("2")).ToList()
}).ToList();

AssertSql(
@"SELECT [b].[Id], [t].[Id], [t].[BlogId], [t].[Name]
FROM [Blogs] AS [b]
LEFT JOIN (
SELECT [p].[Id], [p].[BlogId], [p].[Name]
FROM [Posts] AS [p]
WHERE [p].[Name] LIKE N'%2%'
) AS [t] ON [b].[Id] = [t].[BlogId]
ORDER BY [b].[Id], [t].[Id]");
}
}

[ConditionalFact]
public virtual void Projecting_element_from_correlated_collection_along_with_non_mapped_property()
{
using (CreateDatabase11835())
{
using var context = new MyContext11835(_options);
var result = context.Blogs.Select(
e => new
{
Id = e.Id,
Title = e.Title,
FirstPostName = e.Posts.OrderBy(i => i.Id).FirstOrDefault().Name
}).ToList();

AssertSql(
@"SELECT [b].[Id], (
SELECT TOP(1) [p].[Name]
FROM [Posts] AS [p]
WHERE [b].[Id] = [p].[BlogId]
ORDER BY [p].[Id])
FROM [Blogs] AS [b]");
}
}

private class MyContext11835 : DbContext
{
public DbSet<Blog11835> Blogs { get; set; }
public DbSet<Post11835> Posts { get; set; }

public MyContext11835(DbContextOptions options)
: base(options)
{
}
}

public class Blog11835
{
public int Id { get; set; }
[NotMapped]
public string Title { get; set; }
public List<Post11835> Posts { get; set; }
}
public class Post11835
{
public int Id { get; set; }
public int BlogId { get; set; }
public Blog11835 Blog { get; set; }
public string Name { get; set; }
}
private SqlServerTestStore CreateDatabase11835()
=> CreateTestStore(
() => new MyContext11835(_options),
context =>
{
var b1 = new Blog11835 { Title = "B1" };
var b2 = new Blog11835 { Title = "B2" };
var p11 = new Post11835 { Name = "P11", Blog = b1 };
var p12 = new Post11835 { Name = "P12", Blog = b1 };
var p13 = new Post11835 { Name = "P13", Blog = b1 };
var p21 = new Post11835 { Name = "P21", Blog = b2 };
var p22 = new Post11835 { Name = "P22", Blog = b2 };
context.Blogs.AddRange(b1, b2);
context.Posts.AddRange(p11, p12, p13, p21, p22);
context.SaveChanges();
ClearLog();
});

#endregion

private DbContextOptions _options;

private SqlServerTestStore CreateTestStore<TContext>(
Expand Down
Loading

0 comments on commit 3183f95

Please sign in to comment.