Skip to content

Commit

Permalink
Additional regression tests for issues that have been fixed previously
Browse files Browse the repository at this point in the history
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
  • Loading branch information
maumar committed Oct 6, 2020
1 parent b715a35 commit dadbe42
Show file tree
Hide file tree
Showing 11 changed files with 598 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,9 @@ public override Task Client_eval_followed_by_set_operation_throws_meaningful_exc
[ConditionalTheory(Skip = "issue #17537")]
public override Task SelectMany_predicate_with_non_equality_comparison_with_Take_doesnt_convert_to_join(bool async)
=> base.SelectMany_predicate_with_non_equality_comparison_with_Take_doesnt_convert_to_join(async);

[ConditionalTheory(Skip = "issue #19584")]
public override Task Cast_to_derived_followed_by_include_and_FirstOrDefault(bool async)
=> base.Cast_to_derived_followed_by_include_and_FirstOrDefault(async);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// 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.Threading.Tasks;
using Xunit;

namespace Microsoft.EntityFrameworkCore.Query
{
public abstract class TPTGearsOfWarQueryRelationalTestBase<TFixture> : GearsOfWarQueryRelationalTestBase<TFixture>
Expand All @@ -10,5 +13,11 @@ protected TPTGearsOfWarQueryRelationalTestBase(TFixture fixture)
: base(fixture)
{
}

[ConditionalTheory(Skip = "issue #22691")]
public override async Task Cast_to_derived_followed_by_include_and_FirstOrDefault(bool async)
{
await base.Cast_to_derived_followed_by_include_and_FirstOrDefault(async);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5697,5 +5697,120 @@ public virtual Task Multiple_conditionals_in_projection(bool async)
}
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Composite_key_join_on_groupby_aggregate_projecting_only_grouping_key(bool async)
{
return AssertQueryScalar(
async,
ss => ss.Set<Level1>()
.Join(
ss.Set<Level2>().GroupBy(g => g.Id % 3).Select(g => new { g.Key, Sum = g.Sum(x => x.Id) }),
o => new { o.Id, Condition = true },
i => new { Id = i.Key, Condition = i.Sum > 10, },
(o, i) => i.Key));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Multiple_joins_groupby_predicate(bool async)
{
return AssertQuery(
async,
ss => from l1 in ss.Set<Level1>()
join l2 in ss.Set<Level2>() on l1.Id equals l2.Level1_Optional_Id into grouping1
from l2 in grouping1.DefaultIfEmpty()
join x in (from l3 in ss.Set<Level3>()
group l3 by l3.Name into g
select new { Key = g.Key, Count = g.Count() }) on l1.Name equals x.Key into grouping2
from x in grouping2.DefaultIfEmpty()
where l2.Name != null || x.Count > 0
select new { l1.Id, l1.Name, Foo = l2 == null ? "Foo" : "Bar" },
elementSorter: e => (e.Id, e.Name, e.Foo));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Collection_FirstOrDefault_property_accesses_in_projection(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Level1>()
.Include(x => x.OneToMany_Optional1).ThenInclude(x => x.OneToMany_Optional2)
.Where(l1 => l1.Id < 3)
.Select(l1 => new
{
l1.Id,
Pushdown = l1.OneToMany_Optional1.Where(x => x.Name == "L2 02").FirstOrDefault().Name
}));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Collection_FirstOrDefault_entity_reference_accesses_in_projection(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Level1>()
.Include(x => x.OneToMany_Optional1).ThenInclude(x => x.OneToMany_Optional2)
.Where(l1 => l1.Id < 3)
.Select(l1 => new
{
l1.Id,
Pushdown = l1.OneToMany_Optional1
.Where(x => x.Name == "L2 02")
.FirstOrDefault().OneToOne_Optional_FK2
}));
}

[ConditionalTheory(Skip = "issue #22896")]
[MemberData(nameof(IsAsyncData))]
public virtual Task Collection_FirstOrDefault_entity_collection_accesses_in_projection(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Level1>()
.Where(l1 => l1.Id < 2)
.Select(l1 => new
{
l1.Id,
Pushdown = l1.OneToMany_Optional1
.Where(x => x.Name == "L2 02")
.FirstOrDefault().OneToMany_Optional2.ToList()
}));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Multiple_collection_FirstOrDefault_followed_by_member_access_in_projection(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Level1>()
.Where(l1 => l1.Id < 2)
.Select(l1 => new
{
l1.Id,
Pushdown = l1.OneToMany_Optional1
.Where(x => x.Name == "L2 02")
.FirstOrDefault().OneToMany_Optional2
.OrderBy(x => x.Id)
.FirstOrDefault().Name
}));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projecting_columns_with_same_name_from_different_entities_making_sure_aliasing_works_after_Distinct(bool async)
{
return AssertQuery(
async,
ss => (from l1 in ss.Set<Level1>()
join l2 in ss.Set<Level2>() on l1.Id equals l2.Level1_Optional_Id
join l3 in ss.Set<Level3>() on l2.Id equals l3.Level2_Optional_Id
select new { Id1 = l1.Id, Id2 = l2.Id, Id3 = l3.Id, Name1 = l1.Name, Name2 = l2.Name }).Distinct().Select(x => new { Foo = x.Id1, Bar = x.Id2, Baz = x.Id3 }).Take(10),
elementSorter: e => (e.Foo, e.Bar, e.Baz));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ public override Task Include_collection_with_multiple_orderbys_property(bool asy
return base.Include_collection_with_multiple_orderbys_property(async);
}

[ConditionalTheory(Skip = "Issue#17803")]
public override Task Member_pushdown_with_multiple_collections(bool async)
{
return base.Member_pushdown_with_multiple_collections(async);
}
//[ConditionalTheory(Skip = "Issue#17803")]
//public override Task Member_pushdown_with_multiple_collections(bool async)
//{
// return base.Member_pushdown_with_multiple_collections(async);
//}

// Cannot create DbSet for Level2
public override void Join_with_navigations_in_the_result_selector2()
Expand Down Expand Up @@ -181,5 +181,11 @@ public override void Filtered_include_outer_parameter_used_inside_filter()
{
// TODO: this test can be ran with weak entities once #18191 is fixed and we can use query test infra properly
}

[ConditionalTheory(Skip = "Issue#17803")]
public override Task Multiple_collection_FirstOrDefault_followed_by_member_access_in_projection(bool async)
{
return base.Multiple_collection_FirstOrDefault_followed_by_member_access_in_projection(async);
}
}
}
43 changes: 43 additions & 0 deletions test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7898,6 +7898,49 @@ await AssertQuery(
ss => ss.Set<LocustLeader>().Where(ll => ll is LocustCommander && (ll as LocustCommander).HighCommandId != 0));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Cast_to_derived_followed_by_include_and_FirstOrDefault(bool async)
{
return AssertFirstOrDefault(
async,
ss => ss.Set<LocustLeader>().Where(ll => ll.Name.Contains("Queen")).Cast<LocustCommander>().Include(lc => lc.DefeatedBy),
asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude<LocustCommander>(x => x.DefeatedBy)));

}

[ConditionalTheory(Skip = "issue #22692")]
[MemberData(nameof(IsAsyncData))]
public virtual Task Cast_to_derived_followed_by_multiple_includes(bool async)
{
var expectedIncludes = new IExpectedInclude[]
{
new ExpectedInclude<LocustCommander>(x => x.DefeatedBy),
new ExpectedInclude<Gear>(x => x.Weapons, "DefeatedBy"),
};

return AssertQuery(
async,
ss => ss.Set<LocustLeader>().Where(ll => ll.Name.Contains("Queen")).Cast<LocustCommander>().Include(lc => lc.DefeatedBy).ThenInclude(g => g.Weapons),
elementAsserter: (e, a) => AssertInclude(e, a, expectedIncludes));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Correlated_collection_take(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Gear>().Select(g => new { g.Nickname, Weapons = g.Weapons.Take(10).ToList(), g.CityOfBirth }),
elementSorter: e => e.Nickname,
elementAsserter: (e, a) =>
{
AssertEqual(e.Nickname, a.Nickname);
AssertCollection(e.Weapons, a.Weapons, elementSorter: ee => ee.Id);
AssertEqual(e.CityOfBirth, a.CityOfBirth);
});
}

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

Expand Down
107 changes: 107 additions & 0 deletions test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestModels.Northwind;
using Microsoft.EntityFrameworkCore.TestUtilities;
Expand Down Expand Up @@ -1860,5 +1861,111 @@ public virtual Task Projecting_Length_of_a_string_property_after_FirstOrDefault_
.Select(c => c.Orders.OrderBy(o => o.OrderID).Select(o => o.CustomerID).FirstOrDefault().MaybeScalar(x => x.Length)),
assertOrder: true);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projecting_count_of_navigation_which_is_generic_list(bool async)
{
return AssertQueryScalar(
async,
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => c.Orders.Count),
assertOrder: true);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projecting_count_of_navigation_which_is_generic_collection(bool async)
{
var collectionCount = typeof(ICollection<Order>).GetProperty("Count");

var prm = Expression.Parameter(typeof(Customer), "c");
var selector = Expression.Lambda<Func<Customer, int>>(
Expression.Property(
Expression.Property(prm, "Orders"),
collectionCount),
prm);

return AssertQueryScalar(
async,
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(selector),
assertOrder: true);
}

[ConditionalTheory(Skip = "issue #22701")]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projecting_count_of_navigation_which_is_generic_collection_using_convert(bool async)
{
return AssertQueryScalar(
async,
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => ((ICollection<Order>)c.Orders).Count),
assertOrder: true);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projection_take_projection_doesnt_project_intermittent_column(bool async)
{
return AssertQuery(
async,
ss => ss
.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => new { c.CustomerID, c.City, c.CompanyName })
.Take(10)
.Select(x => new { Aggregate = x.CustomerID + " " + x.City }),
assertOrder: true);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projection_skip_projection_doesnt_project_intermittent_column(bool async)
{
return AssertQuery(
async,
ss => ss
.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => new { c.CustomerID, c.City, c.CompanyName })
.Skip(7)
.Select(x => new { Aggregate = x.CustomerID + " " + x.City }),
assertOrder: true);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projection_Distinct_projection_contains_intermittent_column(bool async)
{
return AssertQuery(
async,
ss => ss
.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => new { c.CustomerID, FirstLetter = c.CustomerID.Substring(0, 1), Foo = "Foo" })
.Distinct()
.Select(x => new { Aggregate = x.FirstLetter + " " + x.Foo }),
elementSorter: e => e.Aggregate);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projection_take_predicate_projection(bool async)
{
return AssertQuery(
async,
ss => ss
.Set<Customer>()
.OrderBy(c => c.CustomerID)
.Select(c => new { c.CustomerID, c.City, c.CompanyName })
.Take(10)
.Where(x => x.CustomerID.StartsWith("A"))
.Select(x => new { Aggregate = x.CustomerID + " " + x.City }),
assertOrder: true);
}
}
}
Loading

0 comments on commit dadbe42

Please sign in to comment.